Compare commits

..

1 Commits

Author SHA1 Message Date
Adam Butterworth
93a569f9ec fix: initial sequence component set 2020-01-14 15:32:58 -05:00
84 changed files with 2230 additions and 5609 deletions

View File

@@ -1,21 +0,0 @@
# Courseware app structure
Currently we have hierarchical courses - they contain sections, subsections, units, and components.
We need data to power each level.
We've made decisions that we're going to re-fetch data at the subsection level under the assumption that
At any given level, you have the following structure:
Parent
Container
Child
Context
The container belongs to the parent module, and is an opportunity for the parent to decide to load more data necessary to load the Child. If the parent has what it needs, it may not use a Container. The Child has an props-only interface. It does _not_ use contexts or redux from the Parent. The child may decide to use a Context internally if that's convenient, but that's a decision independent of anything above the Child in the hierarchy.
This app uses a "model store" - a normalized representation of our API data. This data is kept in an Object with entity IDs as keys, and the entities as values. This allows the application to quickly look up data in the map using only a key. It also means that if the same entity is used in multiple places, there's only one actual representation of it in the client - anyone who wants to use it effectively maintains a reference to it via it's ID.
There are a few kinds of data in the model store. Information from the blocks API - courses, chapters, sequences, and units - are stored together by ID. Into this, we merge course, sequence, and unit metadata from the courses and sequence metadata APIs.

3622
package-lock.json generated
View File

@@ -105,540 +105,88 @@
}
},
"@babel/helper-annotate-as-pure": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.8.3.tgz",
"integrity": "sha512-6o+mJrZBxOoEX77Ezv9zwW7WV8DdluouRKNY/IR5u/YTMuKHgugHOzYWlYvYLpLA9nPsQCAAASpCIbjI9Mv+Uw==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.7.4.tgz",
"integrity": "sha512-2BQmQgECKzYKFPpiycoF9tlb5HA4lrVyAmLLVK177EcQAqjVLciUb2/R+n1boQ9y5ENV3uz2ZqiNw7QMBBw1Og==",
"dev": true,
"requires": {
"@babel/types": "^7.8.3"
},
"dependencies": {
"@babel/types": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz",
"integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==",
"dev": true,
"requires": {
"esutils": "^2.0.2",
"lodash": "^4.17.13",
"to-fast-properties": "^2.0.0"
}
}
"@babel/types": "^7.7.4"
}
},
"@babel/helper-builder-binary-assignment-operator-visitor": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.8.3.tgz",
"integrity": "sha512-5eFOm2SyFPK4Rh3XMMRDjN7lBH0orh3ss0g3rTYZnBQ+r6YPj7lgDyCvPphynHvUrobJmeMignBr6Acw9mAPlw==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.7.4.tgz",
"integrity": "sha512-Biq/d/WtvfftWZ9Uf39hbPBYDUo986m5Bb4zhkeYDGUllF43D+nUe5M6Vuo6/8JDK/0YX/uBdeoQpyaNhNugZQ==",
"dev": true,
"requires": {
"@babel/helper-explode-assignable-expression": "^7.8.3",
"@babel/types": "^7.8.3"
},
"dependencies": {
"@babel/types": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz",
"integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==",
"dev": true,
"requires": {
"esutils": "^2.0.2",
"lodash": "^4.17.13",
"to-fast-properties": "^2.0.0"
}
}
"@babel/helper-explode-assignable-expression": "^7.7.4",
"@babel/types": "^7.7.4"
}
},
"@babel/helper-builder-react-jsx": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.8.3.tgz",
"integrity": "sha512-JT8mfnpTkKNCboTqZsQTdGo3l3Ik3l7QIt9hh0O9DYiwVel37VoJpILKM4YFbP2euF32nkQSb+F9cUk9b7DDXQ==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.7.4.tgz",
"integrity": "sha512-kvbfHJNN9dg4rkEM4xn1s8d1/h6TYNvajy9L1wx4qLn9HFg0IkTsQi4rfBe92nxrPUFcMsHoMV+8rU7MJb3fCA==",
"dev": true,
"requires": {
"@babel/types": "^7.8.3",
"@babel/types": "^7.7.4",
"esutils": "^2.0.0"
},
"dependencies": {
"@babel/types": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz",
"integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==",
"dev": true,
"requires": {
"esutils": "^2.0.2",
"lodash": "^4.17.13",
"to-fast-properties": "^2.0.0"
}
}
}
},
"@babel/helper-call-delegate": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.8.3.tgz",
"integrity": "sha512-6Q05px0Eb+N4/GTyKPPvnkig7Lylw+QzihMpws9iiZQv7ZImf84ZsZpQH7QoWN4n4tm81SnSzPgHw2qtO0Zf3A==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.7.4.tgz",
"integrity": "sha512-8JH9/B7J7tCYJ2PpWVpw9JhPuEVHztagNVuQAFBVFYluRMlpG7F1CgKEgGeL6KFqcsIa92ZYVj6DSc0XwmN1ZA==",
"dev": true,
"requires": {
"@babel/helper-hoist-variables": "^7.8.3",
"@babel/traverse": "^7.8.3",
"@babel/types": "^7.8.3"
},
"dependencies": {
"@babel/code-frame": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
"integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==",
"dev": true,
"requires": {
"@babel/highlight": "^7.8.3"
}
},
"@babel/generator": {
"version": "7.8.4",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.4.tgz",
"integrity": "sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==",
"dev": true,
"requires": {
"@babel/types": "^7.8.3",
"jsesc": "^2.5.1",
"lodash": "^4.17.13",
"source-map": "^0.5.0"
}
},
"@babel/helper-function-name": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz",
"integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==",
"dev": true,
"requires": {
"@babel/helper-get-function-arity": "^7.8.3",
"@babel/template": "^7.8.3",
"@babel/types": "^7.8.3"
}
},
"@babel/helper-get-function-arity": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz",
"integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==",
"dev": true,
"requires": {
"@babel/types": "^7.8.3"
}
},
"@babel/helper-split-export-declaration": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz",
"integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==",
"dev": true,
"requires": {
"@babel/types": "^7.8.3"
}
},
"@babel/highlight": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz",
"integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==",
"dev": true,
"requires": {
"chalk": "^2.0.0",
"esutils": "^2.0.2",
"js-tokens": "^4.0.0"
}
},
"@babel/parser": {
"version": "7.8.4",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz",
"integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==",
"dev": true
},
"@babel/template": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz",
"integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.8.3",
"@babel/parser": "^7.8.3",
"@babel/types": "^7.8.3"
}
},
"@babel/traverse": {
"version": "7.8.4",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.4.tgz",
"integrity": "sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.8.3",
"@babel/generator": "^7.8.4",
"@babel/helper-function-name": "^7.8.3",
"@babel/helper-split-export-declaration": "^7.8.3",
"@babel/parser": "^7.8.4",
"@babel/types": "^7.8.3",
"debug": "^4.1.0",
"globals": "^11.1.0",
"lodash": "^4.17.13"
}
},
"@babel/types": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz",
"integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==",
"dev": true,
"requires": {
"esutils": "^2.0.2",
"lodash": "^4.17.13",
"to-fast-properties": "^2.0.0"
}
},
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
"source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
"dev": true
}
"@babel/helper-hoist-variables": "^7.7.4",
"@babel/traverse": "^7.7.4",
"@babel/types": "^7.7.4"
}
},
"@babel/helper-create-class-features-plugin": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.8.3.tgz",
"integrity": "sha512-qmp4pD7zeTxsv0JNecSBsEmG1ei2MqwJq4YQcK3ZWm/0t07QstWfvuV/vm3Qt5xNMFETn2SZqpMx2MQzbtq+KA==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.7.4.tgz",
"integrity": "sha512-l+OnKACG4uiDHQ/aJT8dwpR+LhCJALxL0mJ6nzjB25e5IPwqV1VOsY7ah6UB1DG+VOXAIMtuC54rFJGiHkxjgA==",
"dev": true,
"requires": {
"@babel/helper-function-name": "^7.8.3",
"@babel/helper-member-expression-to-functions": "^7.8.3",
"@babel/helper-optimise-call-expression": "^7.8.3",
"@babel/helper-plugin-utils": "^7.8.3",
"@babel/helper-replace-supers": "^7.8.3",
"@babel/helper-split-export-declaration": "^7.8.3"
},
"dependencies": {
"@babel/code-frame": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
"integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==",
"dev": true,
"requires": {
"@babel/highlight": "^7.8.3"
}
},
"@babel/helper-function-name": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz",
"integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==",
"dev": true,
"requires": {
"@babel/helper-get-function-arity": "^7.8.3",
"@babel/template": "^7.8.3",
"@babel/types": "^7.8.3"
}
},
"@babel/helper-get-function-arity": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz",
"integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==",
"dev": true,
"requires": {
"@babel/types": "^7.8.3"
}
},
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
},
"@babel/helper-split-export-declaration": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz",
"integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==",
"dev": true,
"requires": {
"@babel/types": "^7.8.3"
}
},
"@babel/highlight": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz",
"integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==",
"dev": true,
"requires": {
"chalk": "^2.0.0",
"esutils": "^2.0.2",
"js-tokens": "^4.0.0"
}
},
"@babel/parser": {
"version": "7.8.4",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz",
"integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==",
"dev": true
},
"@babel/template": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz",
"integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.8.3",
"@babel/parser": "^7.8.3",
"@babel/types": "^7.8.3"
}
},
"@babel/types": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz",
"integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==",
"dev": true,
"requires": {
"esutils": "^2.0.2",
"lodash": "^4.17.13",
"to-fast-properties": "^2.0.0"
}
}
"@babel/helper-function-name": "^7.7.4",
"@babel/helper-member-expression-to-functions": "^7.7.4",
"@babel/helper-optimise-call-expression": "^7.7.4",
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/helper-replace-supers": "^7.7.4",
"@babel/helper-split-export-declaration": "^7.7.4"
}
},
"@babel/helper-create-regexp-features-plugin": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.3.tgz",
"integrity": "sha512-Gcsm1OHCUr9o9TcJln57xhWHtdXbA2pgQ58S0Lxlks0WMGNXuki4+GLfX0p+L2ZkINUGZvfkz8rzoqJQSthI+Q==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.7.4.tgz",
"integrity": "sha512-Mt+jBKaxL0zfOIWrfQpnfYCN7/rS6GKx6CCCfuoqVVd+17R8zNDlzVYmIi9qyb2wOk002NsmSTDymkIygDUH7A==",
"dev": true,
"requires": {
"@babel/helper-regex": "^7.8.3",
"@babel/helper-regex": "^7.4.4",
"regexpu-core": "^4.6.0"
}
},
"@babel/helper-define-map": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.8.3.tgz",
"integrity": "sha512-PoeBYtxoZGtct3md6xZOCWPcKuMuk3IHhgxsRRNtnNShebf4C8YonTSblsK4tvDbm+eJAw2HAPOfCr+Q/YRG/g==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.7.4.tgz",
"integrity": "sha512-v5LorqOa0nVQUvAUTUF3KPastvUt/HzByXNamKQ6RdJRTV7j8rLL+WB5C/MzzWAwOomxDhYFb1wLLxHqox86lg==",
"dev": true,
"requires": {
"@babel/helper-function-name": "^7.8.3",
"@babel/types": "^7.8.3",
"@babel/helper-function-name": "^7.7.4",
"@babel/types": "^7.7.4",
"lodash": "^4.17.13"
},
"dependencies": {
"@babel/code-frame": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
"integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==",
"dev": true,
"requires": {
"@babel/highlight": "^7.8.3"
}
},
"@babel/helper-function-name": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz",
"integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==",
"dev": true,
"requires": {
"@babel/helper-get-function-arity": "^7.8.3",
"@babel/template": "^7.8.3",
"@babel/types": "^7.8.3"
}
},
"@babel/helper-get-function-arity": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz",
"integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==",
"dev": true,
"requires": {
"@babel/types": "^7.8.3"
}
},
"@babel/highlight": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz",
"integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==",
"dev": true,
"requires": {
"chalk": "^2.0.0",
"esutils": "^2.0.2",
"js-tokens": "^4.0.0"
}
},
"@babel/parser": {
"version": "7.8.4",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz",
"integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==",
"dev": true
},
"@babel/template": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz",
"integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.8.3",
"@babel/parser": "^7.8.3",
"@babel/types": "^7.8.3"
}
},
"@babel/types": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz",
"integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==",
"dev": true,
"requires": {
"esutils": "^2.0.2",
"lodash": "^4.17.13",
"to-fast-properties": "^2.0.0"
}
}
}
},
"@babel/helper-explode-assignable-expression": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.8.3.tgz",
"integrity": "sha512-N+8eW86/Kj147bO9G2uclsg5pwfs/fqqY5rwgIL7eTBklgXjcOJ3btzS5iM6AitJcftnY7pm2lGsrJVYLGjzIw==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.7.4.tgz",
"integrity": "sha512-2/SicuFrNSXsZNBxe5UGdLr+HZg+raWBLE9vC98bdYOKX/U6PY0mdGlYUJdtTDPSU0Lw0PNbKKDpwYHJLn2jLg==",
"dev": true,
"requires": {
"@babel/traverse": "^7.8.3",
"@babel/types": "^7.8.3"
},
"dependencies": {
"@babel/code-frame": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
"integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==",
"dev": true,
"requires": {
"@babel/highlight": "^7.8.3"
}
},
"@babel/generator": {
"version": "7.8.4",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.4.tgz",
"integrity": "sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==",
"dev": true,
"requires": {
"@babel/types": "^7.8.3",
"jsesc": "^2.5.1",
"lodash": "^4.17.13",
"source-map": "^0.5.0"
}
},
"@babel/helper-function-name": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz",
"integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==",
"dev": true,
"requires": {
"@babel/helper-get-function-arity": "^7.8.3",
"@babel/template": "^7.8.3",
"@babel/types": "^7.8.3"
}
},
"@babel/helper-get-function-arity": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz",
"integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==",
"dev": true,
"requires": {
"@babel/types": "^7.8.3"
}
},
"@babel/helper-split-export-declaration": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz",
"integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==",
"dev": true,
"requires": {
"@babel/types": "^7.8.3"
}
},
"@babel/highlight": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz",
"integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==",
"dev": true,
"requires": {
"chalk": "^2.0.0",
"esutils": "^2.0.2",
"js-tokens": "^4.0.0"
}
},
"@babel/parser": {
"version": "7.8.4",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz",
"integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==",
"dev": true
},
"@babel/template": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz",
"integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.8.3",
"@babel/parser": "^7.8.3",
"@babel/types": "^7.8.3"
}
},
"@babel/traverse": {
"version": "7.8.4",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.4.tgz",
"integrity": "sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.8.3",
"@babel/generator": "^7.8.4",
"@babel/helper-function-name": "^7.8.3",
"@babel/helper-split-export-declaration": "^7.8.3",
"@babel/parser": "^7.8.4",
"@babel/types": "^7.8.3",
"debug": "^4.1.0",
"globals": "^11.1.0",
"lodash": "^4.17.13"
}
},
"@babel/types": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz",
"integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==",
"dev": true,
"requires": {
"esutils": "^2.0.2",
"lodash": "^4.17.13",
"to-fast-properties": "^2.0.0"
}
},
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
"source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
"dev": true
}
"@babel/traverse": "^7.7.4",
"@babel/types": "^7.7.4"
}
},
"@babel/helper-function-name": {
@@ -662,164 +210,53 @@
}
},
"@babel/helper-hoist-variables": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.8.3.tgz",
"integrity": "sha512-ky1JLOjcDUtSc+xkt0xhYff7Z6ILTAHKmZLHPxAhOP0Nd77O+3nCsd6uSVYur6nJnCI029CrNbYlc0LoPfAPQg==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.7.4.tgz",
"integrity": "sha512-wQC4xyvc1Jo/FnLirL6CEgPgPCa8M74tOdjWpRhQYapz5JC7u3NYU1zCVoVAGCE3EaIP9T1A3iW0WLJ+reZlpQ==",
"dev": true,
"requires": {
"@babel/types": "^7.8.3"
},
"dependencies": {
"@babel/types": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz",
"integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==",
"dev": true,
"requires": {
"esutils": "^2.0.2",
"lodash": "^4.17.13",
"to-fast-properties": "^2.0.0"
}
}
"@babel/types": "^7.7.4"
}
},
"@babel/helper-member-expression-to-functions": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz",
"integrity": "sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.7.4.tgz",
"integrity": "sha512-9KcA1X2E3OjXl/ykfMMInBK+uVdfIVakVe7W7Lg3wfXUNyS3Q1HWLFRwZIjhqiCGbslummPDnmb7vIekS0C1vw==",
"dev": true,
"requires": {
"@babel/types": "^7.8.3"
},
"dependencies": {
"@babel/types": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz",
"integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==",
"dev": true,
"requires": {
"esutils": "^2.0.2",
"lodash": "^4.17.13",
"to-fast-properties": "^2.0.0"
}
}
"@babel/types": "^7.7.4"
}
},
"@babel/helper-module-imports": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz",
"integrity": "sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.7.4.tgz",
"integrity": "sha512-dGcrX6K9l8258WFjyDLJwuVKxR4XZfU0/vTUgOQYWEnRD8mgr+p4d6fCUMq/ys0h4CCt/S5JhbvtyErjWouAUQ==",
"dev": true,
"requires": {
"@babel/types": "^7.8.3"
},
"dependencies": {
"@babel/types": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz",
"integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==",
"dev": true,
"requires": {
"esutils": "^2.0.2",
"lodash": "^4.17.13",
"to-fast-properties": "^2.0.0"
}
}
"@babel/types": "^7.7.4"
}
},
"@babel/helper-module-transforms": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.8.3.tgz",
"integrity": "sha512-C7NG6B7vfBa/pwCOshpMbOYUmrYQDfCpVL/JCRu0ek8B5p8kue1+BCXpg2vOYs7w5ACB9GTOBYQ5U6NwrMg+3Q==",
"version": "7.7.5",
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.7.5.tgz",
"integrity": "sha512-A7pSxyJf1gN5qXVcidwLWydjftUN878VkalhXX5iQDuGyiGK3sOrrKKHF4/A4fwHtnsotv/NipwAeLzY4KQPvw==",
"dev": true,
"requires": {
"@babel/helper-module-imports": "^7.8.3",
"@babel/helper-simple-access": "^7.8.3",
"@babel/helper-split-export-declaration": "^7.8.3",
"@babel/template": "^7.8.3",
"@babel/types": "^7.8.3",
"@babel/helper-module-imports": "^7.7.4",
"@babel/helper-simple-access": "^7.7.4",
"@babel/helper-split-export-declaration": "^7.7.4",
"@babel/template": "^7.7.4",
"@babel/types": "^7.7.4",
"lodash": "^4.17.13"
},
"dependencies": {
"@babel/code-frame": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
"integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==",
"dev": true,
"requires": {
"@babel/highlight": "^7.8.3"
}
},
"@babel/helper-split-export-declaration": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz",
"integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==",
"dev": true,
"requires": {
"@babel/types": "^7.8.3"
}
},
"@babel/highlight": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz",
"integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==",
"dev": true,
"requires": {
"chalk": "^2.0.0",
"esutils": "^2.0.2",
"js-tokens": "^4.0.0"
}
},
"@babel/parser": {
"version": "7.8.4",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz",
"integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==",
"dev": true
},
"@babel/template": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz",
"integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.8.3",
"@babel/parser": "^7.8.3",
"@babel/types": "^7.8.3"
}
},
"@babel/types": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz",
"integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==",
"dev": true,
"requires": {
"esutils": "^2.0.2",
"lodash": "^4.17.13",
"to-fast-properties": "^2.0.0"
}
}
}
},
"@babel/helper-optimise-call-expression": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz",
"integrity": "sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.7.4.tgz",
"integrity": "sha512-VB7gWZ2fDkSuqW6b1AKXkJWO5NyNI3bFL/kK79/30moK57blr6NbH8xcl2XcKCwOmJosftWunZqfO84IGq3ZZg==",
"dev": true,
"requires": {
"@babel/types": "^7.8.3"
},
"dependencies": {
"@babel/types": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz",
"integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==",
"dev": true,
"requires": {
"esutils": "^2.0.2",
"lodash": "^4.17.13",
"to-fast-properties": "^2.0.0"
}
}
"@babel/types": "^7.7.4"
}
},
"@babel/helper-plugin-utils": {
@@ -829,355 +266,47 @@
"dev": true
},
"@babel/helper-regex": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.8.3.tgz",
"integrity": "sha512-BWt0QtYv/cg/NecOAZMdcn/waj/5P26DR4mVLXfFtDokSR6fyuG0Pj+e2FqtSME+MqED1khnSMulkmGl8qWiUQ==",
"version": "7.5.5",
"resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.5.5.tgz",
"integrity": "sha512-CkCYQLkfkiugbRDO8eZn6lRuR8kzZoGXCg3149iTk5se7g6qykSpy3+hELSwquhu+TgHn8nkLiBwHvNX8Hofcw==",
"dev": true,
"requires": {
"lodash": "^4.17.13"
}
},
"@babel/helper-remap-async-to-generator": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.8.3.tgz",
"integrity": "sha512-kgwDmw4fCg7AVgS4DukQR/roGp+jP+XluJE5hsRZwxCYGg+Rv9wSGErDWhlI90FODdYfd4xG4AQRiMDjjN0GzA==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.7.4.tgz",
"integrity": "sha512-Sk4xmtVdM9sA/jCI80f+KS+Md+ZHIpjuqmYPk1M7F/upHou5e4ReYmExAiu6PVe65BhJPZA2CY9x9k4BqE5klw==",
"dev": true,
"requires": {
"@babel/helper-annotate-as-pure": "^7.8.3",
"@babel/helper-wrap-function": "^7.8.3",
"@babel/template": "^7.8.3",
"@babel/traverse": "^7.8.3",
"@babel/types": "^7.8.3"
},
"dependencies": {
"@babel/code-frame": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
"integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==",
"dev": true,
"requires": {
"@babel/highlight": "^7.8.3"
}
},
"@babel/generator": {
"version": "7.8.4",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.4.tgz",
"integrity": "sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==",
"dev": true,
"requires": {
"@babel/types": "^7.8.3",
"jsesc": "^2.5.1",
"lodash": "^4.17.13",
"source-map": "^0.5.0"
}
},
"@babel/helper-function-name": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz",
"integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==",
"dev": true,
"requires": {
"@babel/helper-get-function-arity": "^7.8.3",
"@babel/template": "^7.8.3",
"@babel/types": "^7.8.3"
}
},
"@babel/helper-get-function-arity": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz",
"integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==",
"dev": true,
"requires": {
"@babel/types": "^7.8.3"
}
},
"@babel/helper-split-export-declaration": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz",
"integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==",
"dev": true,
"requires": {
"@babel/types": "^7.8.3"
}
},
"@babel/highlight": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz",
"integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==",
"dev": true,
"requires": {
"chalk": "^2.0.0",
"esutils": "^2.0.2",
"js-tokens": "^4.0.0"
}
},
"@babel/parser": {
"version": "7.8.4",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz",
"integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==",
"dev": true
},
"@babel/template": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz",
"integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.8.3",
"@babel/parser": "^7.8.3",
"@babel/types": "^7.8.3"
}
},
"@babel/traverse": {
"version": "7.8.4",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.4.tgz",
"integrity": "sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.8.3",
"@babel/generator": "^7.8.4",
"@babel/helper-function-name": "^7.8.3",
"@babel/helper-split-export-declaration": "^7.8.3",
"@babel/parser": "^7.8.4",
"@babel/types": "^7.8.3",
"debug": "^4.1.0",
"globals": "^11.1.0",
"lodash": "^4.17.13"
}
},
"@babel/types": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz",
"integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==",
"dev": true,
"requires": {
"esutils": "^2.0.2",
"lodash": "^4.17.13",
"to-fast-properties": "^2.0.0"
}
},
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
"source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
"dev": true
}
"@babel/helper-annotate-as-pure": "^7.7.4",
"@babel/helper-wrap-function": "^7.7.4",
"@babel/template": "^7.7.4",
"@babel/traverse": "^7.7.4",
"@babel/types": "^7.7.4"
}
},
"@babel/helper-replace-supers": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.8.3.tgz",
"integrity": "sha512-xOUssL6ho41U81etpLoT2RTdvdus4VfHamCuAm4AHxGr+0it5fnwoVdwUJ7GFEqCsQYzJUhcbsN9wB9apcYKFA==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.7.4.tgz",
"integrity": "sha512-pP0tfgg9hsZWo5ZboYGuBn/bbYT/hdLPVSS4NMmiRJdwWhP0IznPwN9AE1JwyGsjSPLC364I0Qh5p+EPkGPNpg==",
"dev": true,
"requires": {
"@babel/helper-member-expression-to-functions": "^7.8.3",
"@babel/helper-optimise-call-expression": "^7.8.3",
"@babel/traverse": "^7.8.3",
"@babel/types": "^7.8.3"
},
"dependencies": {
"@babel/code-frame": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
"integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==",
"dev": true,
"requires": {
"@babel/highlight": "^7.8.3"
}
},
"@babel/generator": {
"version": "7.8.4",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.4.tgz",
"integrity": "sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==",
"dev": true,
"requires": {
"@babel/types": "^7.8.3",
"jsesc": "^2.5.1",
"lodash": "^4.17.13",
"source-map": "^0.5.0"
}
},
"@babel/helper-function-name": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz",
"integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==",
"dev": true,
"requires": {
"@babel/helper-get-function-arity": "^7.8.3",
"@babel/template": "^7.8.3",
"@babel/types": "^7.8.3"
}
},
"@babel/helper-get-function-arity": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz",
"integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==",
"dev": true,
"requires": {
"@babel/types": "^7.8.3"
}
},
"@babel/helper-split-export-declaration": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz",
"integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==",
"dev": true,
"requires": {
"@babel/types": "^7.8.3"
}
},
"@babel/highlight": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz",
"integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==",
"dev": true,
"requires": {
"chalk": "^2.0.0",
"esutils": "^2.0.2",
"js-tokens": "^4.0.0"
}
},
"@babel/parser": {
"version": "7.8.4",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz",
"integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==",
"dev": true
},
"@babel/template": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz",
"integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.8.3",
"@babel/parser": "^7.8.3",
"@babel/types": "^7.8.3"
}
},
"@babel/traverse": {
"version": "7.8.4",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.4.tgz",
"integrity": "sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.8.3",
"@babel/generator": "^7.8.4",
"@babel/helper-function-name": "^7.8.3",
"@babel/helper-split-export-declaration": "^7.8.3",
"@babel/parser": "^7.8.4",
"@babel/types": "^7.8.3",
"debug": "^4.1.0",
"globals": "^11.1.0",
"lodash": "^4.17.13"
}
},
"@babel/types": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz",
"integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==",
"dev": true,
"requires": {
"esutils": "^2.0.2",
"lodash": "^4.17.13",
"to-fast-properties": "^2.0.0"
}
},
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
"source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
"dev": true
}
"@babel/helper-member-expression-to-functions": "^7.7.4",
"@babel/helper-optimise-call-expression": "^7.7.4",
"@babel/traverse": "^7.7.4",
"@babel/types": "^7.7.4"
}
},
"@babel/helper-simple-access": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz",
"integrity": "sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.7.4.tgz",
"integrity": "sha512-zK7THeEXfan7UlWsG2A6CI/L9jVnI5+xxKZOdej39Y0YtDYKx9raHk5F2EtK9K8DHRTihYwg20ADt9S36GR78A==",
"dev": true,
"requires": {
"@babel/template": "^7.8.3",
"@babel/types": "^7.8.3"
},
"dependencies": {
"@babel/code-frame": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
"integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==",
"dev": true,
"requires": {
"@babel/highlight": "^7.8.3"
}
},
"@babel/highlight": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz",
"integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==",
"dev": true,
"requires": {
"chalk": "^2.0.0",
"esutils": "^2.0.2",
"js-tokens": "^4.0.0"
}
},
"@babel/parser": {
"version": "7.8.4",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz",
"integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==",
"dev": true
},
"@babel/template": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz",
"integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.8.3",
"@babel/parser": "^7.8.3",
"@babel/types": "^7.8.3"
}
},
"@babel/types": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz",
"integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==",
"dev": true,
"requires": {
"esutils": "^2.0.2",
"lodash": "^4.17.13",
"to-fast-properties": "^2.0.0"
}
}
"@babel/template": "^7.7.4",
"@babel/types": "^7.7.4"
}
},
"@babel/helper-split-export-declaration": {
@@ -1190,144 +319,15 @@
}
},
"@babel/helper-wrap-function": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.8.3.tgz",
"integrity": "sha512-LACJrbUET9cQDzb6kG7EeD7+7doC3JNvUgTEQOx2qaO1fKlzE/Bf05qs9w1oXQMmXlPO65lC3Tq9S6gZpTErEQ==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.7.4.tgz",
"integrity": "sha512-VsfzZt6wmsocOaVU0OokwrIytHND55yvyT4BPB9AIIgwr8+x7617hetdJTsuGwygN5RC6mxA9EJztTjuwm2ofg==",
"dev": true,
"requires": {
"@babel/helper-function-name": "^7.8.3",
"@babel/template": "^7.8.3",
"@babel/traverse": "^7.8.3",
"@babel/types": "^7.8.3"
},
"dependencies": {
"@babel/code-frame": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
"integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==",
"dev": true,
"requires": {
"@babel/highlight": "^7.8.3"
}
},
"@babel/generator": {
"version": "7.8.4",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.4.tgz",
"integrity": "sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==",
"dev": true,
"requires": {
"@babel/types": "^7.8.3",
"jsesc": "^2.5.1",
"lodash": "^4.17.13",
"source-map": "^0.5.0"
}
},
"@babel/helper-function-name": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz",
"integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==",
"dev": true,
"requires": {
"@babel/helper-get-function-arity": "^7.8.3",
"@babel/template": "^7.8.3",
"@babel/types": "^7.8.3"
}
},
"@babel/helper-get-function-arity": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz",
"integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==",
"dev": true,
"requires": {
"@babel/types": "^7.8.3"
}
},
"@babel/helper-split-export-declaration": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz",
"integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==",
"dev": true,
"requires": {
"@babel/types": "^7.8.3"
}
},
"@babel/highlight": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz",
"integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==",
"dev": true,
"requires": {
"chalk": "^2.0.0",
"esutils": "^2.0.2",
"js-tokens": "^4.0.0"
}
},
"@babel/parser": {
"version": "7.8.4",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz",
"integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==",
"dev": true
},
"@babel/template": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz",
"integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.8.3",
"@babel/parser": "^7.8.3",
"@babel/types": "^7.8.3"
}
},
"@babel/traverse": {
"version": "7.8.4",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.4.tgz",
"integrity": "sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.8.3",
"@babel/generator": "^7.8.4",
"@babel/helper-function-name": "^7.8.3",
"@babel/helper-split-export-declaration": "^7.8.3",
"@babel/parser": "^7.8.4",
"@babel/types": "^7.8.3",
"debug": "^4.1.0",
"globals": "^11.1.0",
"lodash": "^4.17.13"
}
},
"@babel/types": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz",
"integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==",
"dev": true,
"requires": {
"esutils": "^2.0.2",
"lodash": "^4.17.13",
"to-fast-properties": "^2.0.0"
}
},
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
"source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
"dev": true
}
"@babel/helper-function-name": "^7.7.4",
"@babel/template": "^7.7.4",
"@babel/traverse": "^7.7.4",
"@babel/types": "^7.7.4"
}
},
"@babel/helpers": {
@@ -1359,22 +359,14 @@
"dev": true
},
"@babel/plugin-proposal-async-generator-functions": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.8.3.tgz",
"integrity": "sha512-NZ9zLv848JsV3hs8ryEh7Uaz/0KsmPLqv0+PdkDJL1cJy0K4kOCFa8zc1E3mp+RHPQcpdfb/6GovEsW4VDrOMw==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.7.4.tgz",
"integrity": "sha512-1ypyZvGRXriY/QP668+s8sFr2mqinhkRDMPSQLNghCQE+GAkFtp+wkHVvg2+Hdki8gwP+NFzJBJ/N1BfzCCDEw==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.3",
"@babel/helper-remap-async-to-generator": "^7.8.3",
"@babel/plugin-syntax-async-generators": "^7.8.0"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/helper-remap-async-to-generator": "^7.7.4",
"@babel/plugin-syntax-async-generators": "^7.7.4"
}
},
"@babel/plugin-proposal-class-properties": {
@@ -1388,48 +380,34 @@
}
},
"@babel/plugin-proposal-dynamic-import": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.8.3.tgz",
"integrity": "sha512-NyaBbyLFXFLT9FP+zk0kYlUlA8XtCUbehs67F0nnEg7KICgMc2mNkIeu9TYhKzyXMkrapZFwAhXLdnt4IYHy1w==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.7.4.tgz",
"integrity": "sha512-StH+nGAdO6qDB1l8sZ5UBV8AC3F2VW2I8Vfld73TMKyptMU9DY5YsJAS8U81+vEtxcH3Y/La0wG0btDrhpnhjQ==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.3",
"@babel/plugin-syntax-dynamic-import": "^7.8.0"
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/plugin-syntax-dynamic-import": "^7.7.4"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
},
"@babel/plugin-syntax-dynamic-import": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz",
"integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.7.4.tgz",
"integrity": "sha512-jHQW0vbRGvwQNgyVxwDh4yuXu4bH1f5/EICJLAhl1SblLs2CDhrsmCk+v5XLdE9wxtAFRyxx+P//Iw+a5L/tTg==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.0"
"@babel/helper-plugin-utils": "^7.0.0"
}
}
}
},
"@babel/plugin-proposal-json-strings": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.8.3.tgz",
"integrity": "sha512-KGhQNZ3TVCQG/MjRbAUwuH+14y9q0tpxs1nWWs3pbSleRdDro9SAMMDyye8HhY1gqZ7/NqIc8SKhya0wRDgP1Q==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.7.4.tgz",
"integrity": "sha512-wQvt3akcBTfLU/wYoqm/ws7YOAQKu8EVJEvHip/mzkNtjaclQoCCIqKXFP5/eyfnfbQCDV3OLRIK3mIVyXuZlw==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.3",
"@babel/plugin-syntax-json-strings": "^7.8.0"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/plugin-syntax-json-strings": "^7.7.4"
}
},
"@babel/plugin-proposal-object-rest-spread": {
@@ -1443,56 +421,32 @@
}
},
"@babel/plugin-proposal-optional-catch-binding": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.8.3.tgz",
"integrity": "sha512-0gkX7J7E+AtAw9fcwlVQj8peP61qhdg/89D5swOkjYbkboA2CVckn3kiyum1DE0wskGb7KJJxBdyEBApDLLVdw==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.7.4.tgz",
"integrity": "sha512-DyM7U2bnsQerCQ+sejcTNZh8KQEUuC3ufzdnVnSiUv/qoGJp2Z3hanKL18KDhsBT5Wj6a7CMT5mdyCNJsEaA9w==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.3",
"@babel/plugin-syntax-optional-catch-binding": "^7.8.0"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/plugin-syntax-optional-catch-binding": "^7.7.4"
}
},
"@babel/plugin-proposal-unicode-property-regex": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.8.3.tgz",
"integrity": "sha512-1/1/rEZv2XGweRwwSkLpY+s60za9OZ1hJs4YDqFHCw0kYWYwL5IFljVY1MYBL+weT1l9pokDO2uhSTLVxzoHkQ==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.7.4.tgz",
"integrity": "sha512-cHgqHgYvffluZk85dJ02vloErm3Y6xtH+2noOBOJ2kXOJH3aVCDnj5eR/lVNlTnYu4hndAPJD3rTFjW3qee0PA==",
"dev": true,
"requires": {
"@babel/helper-create-regexp-features-plugin": "^7.8.3",
"@babel/helper-plugin-utils": "^7.8.3"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-create-regexp-features-plugin": "^7.7.4",
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-syntax-async-generators": {
"version": "7.8.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
"integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.7.4.tgz",
"integrity": "sha512-Li4+EjSpBgxcsmeEF8IFcfV/+yJGxHXDirDkEoyFjumuwbmfCVHUt0HuowD/iGM7OhIRyXJH9YXxqiH6N815+g==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.0"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-syntax-dynamic-import": {
@@ -1505,37 +459,21 @@
}
},
"@babel/plugin-syntax-json-strings": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
"integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.7.4.tgz",
"integrity": "sha512-QpGupahTQW1mHRXddMG5srgpHWqRLwJnJZKXTigB9RPFCCGbDGCgBeM/iC82ICXp414WeYx/tD54w7M2qRqTMg==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.0"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-syntax-jsx": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.8.3.tgz",
"integrity": "sha512-WxdW9xyLgBdefoo0Ynn3MRSkhe5tFVxxKNVdnZSh318WrG2e2jH+E9wd/++JsqcLJZPfz87njQJ8j2Upjm0M0A==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.7.4.tgz",
"integrity": "sha512-wuy6fiMe9y7HeZBWXYCGt2RGxZOj0BImZ9EyXJVnVGBKO/Br592rbR3rtIQn0eQhAk9vqaKP5n8tVqEFBQMfLg==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.3"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-syntax-object-rest-spread": {
@@ -1548,814 +486,368 @@
}
},
"@babel/plugin-syntax-optional-catch-binding": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
"integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.7.4.tgz",
"integrity": "sha512-4ZSuzWgFxqHRE31Glu+fEr/MirNZOMYmD/0BhBWyLyOOQz/gTAl7QmWm2hX1QxEIXsr2vkdlwxIzTyiYRC4xcQ==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.0"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-transform-arrow-functions": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.8.3.tgz",
"integrity": "sha512-0MRF+KC8EqH4dbuITCWwPSzsyO3HIWWlm30v8BbbpOrS1B++isGxPnnuq/IZvOX5J2D/p7DQalQm+/2PnlKGxg==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.7.4.tgz",
"integrity": "sha512-zUXy3e8jBNPiffmqkHRNDdZM2r8DWhCB7HhcoyZjiK1TxYEluLHAvQuYnTT+ARqRpabWqy/NHkO6e3MsYB5YfA==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.3"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-transform-async-to-generator": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.8.3.tgz",
"integrity": "sha512-imt9tFLD9ogt56Dd5CI/6XgpukMwd/fLGSrix2httihVe7LOGVPhyhMh1BU5kDM7iHD08i8uUtmV2sWaBFlHVQ==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.7.4.tgz",
"integrity": "sha512-zpUTZphp5nHokuy8yLlyafxCJ0rSlFoSHypTUWgpdwoDXWQcseaect7cJ8Ppk6nunOM6+5rPMkod4OYKPR5MUg==",
"dev": true,
"requires": {
"@babel/helper-module-imports": "^7.8.3",
"@babel/helper-plugin-utils": "^7.8.3",
"@babel/helper-remap-async-to-generator": "^7.8.3"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-module-imports": "^7.7.4",
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/helper-remap-async-to-generator": "^7.7.4"
}
},
"@babel/plugin-transform-block-scoped-functions": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.8.3.tgz",
"integrity": "sha512-vo4F2OewqjbB1+yaJ7k2EJFHlTP3jR634Z9Cj9itpqNjuLXvhlVxgnjsHsdRgASR8xYDrx6onw4vW5H6We0Jmg==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.7.4.tgz",
"integrity": "sha512-kqtQzwtKcpPclHYjLK//3lH8OFsCDuDJBaFhVwf8kqdnF6MN4l618UDlcA7TfRs3FayrHj+svYnSX8MC9zmUyQ==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.3"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-transform-block-scoping": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.8.3.tgz",
"integrity": "sha512-pGnYfm7RNRgYRi7bids5bHluENHqJhrV4bCZRwc5GamaWIIs07N4rZECcmJL6ZClwjDz1GbdMZFtPs27hTB06w==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.7.4.tgz",
"integrity": "sha512-2VBe9u0G+fDt9B5OV5DQH4KBf5DoiNkwFKOz0TCvBWvdAN2rOykCTkrL+jTLxfCAm76l9Qo5OqL7HBOx2dWggg==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.3",
"@babel/helper-plugin-utils": "^7.0.0",
"lodash": "^4.17.13"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
}
},
"@babel/plugin-transform-classes": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.8.3.tgz",
"integrity": "sha512-SjT0cwFJ+7Rbr1vQsvphAHwUHvSUPmMjMU/0P59G8U2HLFqSa082JO7zkbDNWs9kH/IUqpHI6xWNesGf8haF1w==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.7.4.tgz",
"integrity": "sha512-sK1mjWat7K+buWRuImEzjNf68qrKcrddtpQo3swi9j7dUcG6y6R6+Di039QN2bD1dykeswlagupEmpOatFHHUg==",
"dev": true,
"requires": {
"@babel/helper-annotate-as-pure": "^7.8.3",
"@babel/helper-define-map": "^7.8.3",
"@babel/helper-function-name": "^7.8.3",
"@babel/helper-optimise-call-expression": "^7.8.3",
"@babel/helper-plugin-utils": "^7.8.3",
"@babel/helper-replace-supers": "^7.8.3",
"@babel/helper-split-export-declaration": "^7.8.3",
"@babel/helper-annotate-as-pure": "^7.7.4",
"@babel/helper-define-map": "^7.7.4",
"@babel/helper-function-name": "^7.7.4",
"@babel/helper-optimise-call-expression": "^7.7.4",
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/helper-replace-supers": "^7.7.4",
"@babel/helper-split-export-declaration": "^7.7.4",
"globals": "^11.1.0"
},
"dependencies": {
"@babel/code-frame": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
"integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==",
"dev": true,
"requires": {
"@babel/highlight": "^7.8.3"
}
},
"@babel/helper-function-name": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz",
"integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==",
"dev": true,
"requires": {
"@babel/helper-get-function-arity": "^7.8.3",
"@babel/template": "^7.8.3",
"@babel/types": "^7.8.3"
}
},
"@babel/helper-get-function-arity": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz",
"integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==",
"dev": true,
"requires": {
"@babel/types": "^7.8.3"
}
},
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
},
"@babel/helper-split-export-declaration": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz",
"integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==",
"dev": true,
"requires": {
"@babel/types": "^7.8.3"
}
},
"@babel/highlight": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz",
"integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==",
"dev": true,
"requires": {
"chalk": "^2.0.0",
"esutils": "^2.0.2",
"js-tokens": "^4.0.0"
}
},
"@babel/parser": {
"version": "7.8.4",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz",
"integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==",
"dev": true
},
"@babel/template": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz",
"integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.8.3",
"@babel/parser": "^7.8.3",
"@babel/types": "^7.8.3"
}
},
"@babel/types": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz",
"integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==",
"dev": true,
"requires": {
"esutils": "^2.0.2",
"lodash": "^4.17.13",
"to-fast-properties": "^2.0.0"
}
}
}
},
"@babel/plugin-transform-computed-properties": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.8.3.tgz",
"integrity": "sha512-O5hiIpSyOGdrQZRQ2ccwtTVkgUDBBiCuK//4RJ6UfePllUTCENOzKxfh6ulckXKc0DixTFLCfb2HVkNA7aDpzA==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.7.4.tgz",
"integrity": "sha512-bSNsOsZnlpLLyQew35rl4Fma3yKWqK3ImWMSC/Nc+6nGjC9s5NFWAer1YQ899/6s9HxO2zQC1WoFNfkOqRkqRQ==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.3"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-transform-destructuring": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.8.3.tgz",
"integrity": "sha512-H4X646nCkiEcHZUZaRkhE2XVsoz0J/1x3VVujnn96pSoGCtKPA99ZZA+va+gK+92Zycd6OBKCD8tDb/731bhgQ==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.7.4.tgz",
"integrity": "sha512-4jFMXI1Cu2aXbcXXl8Lr6YubCn6Oc7k9lLsu8v61TZh+1jny2BWmdtvY9zSUlLdGUvcy9DMAWyZEOqjsbeg/wA==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.3"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-transform-dotall-regex": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.8.3.tgz",
"integrity": "sha512-kLs1j9Nn4MQoBYdRXH6AeaXMbEJFaFu/v1nQkvib6QzTj8MZI5OQzqmD83/2jEM1z0DLilra5aWO5YpyC0ALIw==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.7.4.tgz",
"integrity": "sha512-mk0cH1zyMa/XHeb6LOTXTbG7uIJ8Rrjlzu91pUx/KS3JpcgaTDwMS8kM+ar8SLOvlL2Lofi4CGBAjCo3a2x+lw==",
"dev": true,
"requires": {
"@babel/helper-create-regexp-features-plugin": "^7.8.3",
"@babel/helper-plugin-utils": "^7.8.3"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-create-regexp-features-plugin": "^7.7.4",
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-transform-duplicate-keys": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.8.3.tgz",
"integrity": "sha512-s8dHiBUbcbSgipS4SMFuWGqCvyge5V2ZeAWzR6INTVC3Ltjig/Vw1G2Gztv0vU/hRG9X8IvKvYdoksnUfgXOEQ==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.7.4.tgz",
"integrity": "sha512-g1y4/G6xGWMD85Tlft5XedGaZBCIVN+/P0bs6eabmcPP9egFleMAo65OOjlhcz1njpwagyY3t0nsQC9oTFegJA==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.3"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-transform-exponentiation-operator": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.8.3.tgz",
"integrity": "sha512-zwIpuIymb3ACcInbksHaNcR12S++0MDLKkiqXHl3AzpgdKlFNhog+z/K0+TGW+b0w5pgTq4H6IwV/WhxbGYSjQ==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.7.4.tgz",
"integrity": "sha512-MCqiLfCKm6KEA1dglf6Uqq1ElDIZwFuzz1WH5mTf8k2uQSxEJMbOIEh7IZv7uichr7PMfi5YVSrr1vz+ipp7AQ==",
"dev": true,
"requires": {
"@babel/helper-builder-binary-assignment-operator-visitor": "^7.8.3",
"@babel/helper-plugin-utils": "^7.8.3"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-builder-binary-assignment-operator-visitor": "^7.7.4",
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-transform-for-of": {
"version": "7.8.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.8.4.tgz",
"integrity": "sha512-iAXNlOWvcYUYoV8YIxwS7TxGRJcxyl8eQCfT+A5j8sKUzRFvJdcyjp97jL2IghWSRDaL2PU2O2tX8Cu9dTBq5A==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.7.4.tgz",
"integrity": "sha512-zZ1fD1B8keYtEcKF+M1TROfeHTKnijcVQm0yO/Yu1f7qoDoxEIc/+GX6Go430Bg84eM/xwPFp0+h4EbZg7epAA==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.3"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-transform-function-name": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.8.3.tgz",
"integrity": "sha512-rO/OnDS78Eifbjn5Py9v8y0aR+aSYhDhqAwVfsTl0ERuMZyr05L1aFSCJnbv2mmsLkit/4ReeQ9N2BgLnOcPCQ==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.7.4.tgz",
"integrity": "sha512-E/x09TvjHNhsULs2IusN+aJNRV5zKwxu1cpirZyRPw+FyyIKEHPXTsadj48bVpc1R5Qq1B5ZkzumuFLytnbT6g==",
"dev": true,
"requires": {
"@babel/helper-function-name": "^7.8.3",
"@babel/helper-plugin-utils": "^7.8.3"
},
"dependencies": {
"@babel/code-frame": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
"integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==",
"dev": true,
"requires": {
"@babel/highlight": "^7.8.3"
}
},
"@babel/helper-function-name": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz",
"integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==",
"dev": true,
"requires": {
"@babel/helper-get-function-arity": "^7.8.3",
"@babel/template": "^7.8.3",
"@babel/types": "^7.8.3"
}
},
"@babel/helper-get-function-arity": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz",
"integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==",
"dev": true,
"requires": {
"@babel/types": "^7.8.3"
}
},
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
},
"@babel/highlight": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz",
"integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==",
"dev": true,
"requires": {
"chalk": "^2.0.0",
"esutils": "^2.0.2",
"js-tokens": "^4.0.0"
}
},
"@babel/parser": {
"version": "7.8.4",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz",
"integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==",
"dev": true
},
"@babel/template": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz",
"integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.8.3",
"@babel/parser": "^7.8.3",
"@babel/types": "^7.8.3"
}
},
"@babel/types": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz",
"integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==",
"dev": true,
"requires": {
"esutils": "^2.0.2",
"lodash": "^4.17.13",
"to-fast-properties": "^2.0.0"
}
}
"@babel/helper-function-name": "^7.7.4",
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-transform-literals": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.8.3.tgz",
"integrity": "sha512-3Tqf8JJ/qB7TeldGl+TT55+uQei9JfYaregDcEAyBZ7akutriFrt6C/wLYIer6OYhleVQvH/ntEhjE/xMmy10A==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.7.4.tgz",
"integrity": "sha512-X2MSV7LfJFm4aZfxd0yLVFrEXAgPqYoDG53Br/tCKiKYfX0MjVjQeWPIhPHHsCqzwQANq+FLN786fF5rgLS+gw==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.3"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-transform-member-expression-literals": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.8.3.tgz",
"integrity": "sha512-3Wk2EXhnw+rP+IDkK6BdtPKsUE5IeZ6QOGrPYvw52NwBStw9V1ZVzxgK6fSKSxqUvH9eQPR3tm3cOq79HlsKYA==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.7.4.tgz",
"integrity": "sha512-9VMwMO7i69LHTesL0RdGy93JU6a+qOPuvB4F4d0kR0zyVjJRVJRaoaGjhtki6SzQUu8yen/vxPKN6CWnCUw6bA==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.3"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-transform-modules-amd": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.8.3.tgz",
"integrity": "sha512-MadJiU3rLKclzT5kBH4yxdry96odTUwuqrZM+GllFI/VhxfPz+k9MshJM+MwhfkCdxxclSbSBbUGciBngR+kEQ==",
"version": "7.7.5",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.7.5.tgz",
"integrity": "sha512-CT57FG4A2ZUNU1v+HdvDSDrjNWBrtCmSH6YbbgN3Lrf0Di/q/lWRxZrE72p3+HCCz9UjfZOEBdphgC0nzOS6DQ==",
"dev": true,
"requires": {
"@babel/helper-module-transforms": "^7.8.3",
"@babel/helper-plugin-utils": "^7.8.3",
"@babel/helper-module-transforms": "^7.7.5",
"@babel/helper-plugin-utils": "^7.0.0",
"babel-plugin-dynamic-import-node": "^2.3.0"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
}
},
"@babel/plugin-transform-modules-commonjs": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.8.3.tgz",
"integrity": "sha512-JpdMEfA15HZ/1gNuB9XEDlZM1h/gF/YOH7zaZzQu2xCFRfwc01NXBMHHSTT6hRjlXJJs5x/bfODM3LiCk94Sxg==",
"version": "7.7.5",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.7.5.tgz",
"integrity": "sha512-9Cq4zTFExwFhQI6MT1aFxgqhIsMWQWDVwOgLzl7PTWJHsNaqFvklAU+Oz6AQLAS0dJKTwZSOCo20INwktxpi3Q==",
"dev": true,
"requires": {
"@babel/helper-module-transforms": "^7.8.3",
"@babel/helper-plugin-utils": "^7.8.3",
"@babel/helper-simple-access": "^7.8.3",
"@babel/helper-module-transforms": "^7.7.5",
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/helper-simple-access": "^7.7.4",
"babel-plugin-dynamic-import-node": "^2.3.0"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
}
},
"@babel/plugin-transform-modules-systemjs": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.8.3.tgz",
"integrity": "sha512-8cESMCJjmArMYqa9AO5YuMEkE4ds28tMpZcGZB/jl3n0ZzlsxOAi3mC+SKypTfT8gjMupCnd3YiXCkMjj2jfOg==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.7.4.tgz",
"integrity": "sha512-y2c96hmcsUi6LrMqvmNDPBBiGCiQu0aYqpHatVVu6kD4mFEXKjyNxd/drc18XXAf9dv7UXjrZwBVmTTGaGP8iw==",
"dev": true,
"requires": {
"@babel/helper-hoist-variables": "^7.8.3",
"@babel/helper-module-transforms": "^7.8.3",
"@babel/helper-plugin-utils": "^7.8.3",
"@babel/helper-hoist-variables": "^7.7.4",
"@babel/helper-plugin-utils": "^7.0.0",
"babel-plugin-dynamic-import-node": "^2.3.0"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
}
},
"@babel/plugin-transform-modules-umd": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.8.3.tgz",
"integrity": "sha512-evhTyWhbwbI3/U6dZAnx/ePoV7H6OUG+OjiJFHmhr9FPn0VShjwC2kdxqIuQ/+1P50TMrneGzMeyMTFOjKSnAw==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.7.4.tgz",
"integrity": "sha512-u2B8TIi0qZI4j8q4C51ktfO7E3cQ0qnaXFI1/OXITordD40tt17g/sXqgNNCcMTcBFKrUPcGDx+TBJuZxLx7tw==",
"dev": true,
"requires": {
"@babel/helper-module-transforms": "^7.8.3",
"@babel/helper-plugin-utils": "^7.8.3"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-module-transforms": "^7.7.4",
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-transform-named-capturing-groups-regex": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.8.3.tgz",
"integrity": "sha512-f+tF/8UVPU86TrCb06JoPWIdDpTNSGGcAtaD9mLP0aYGA0OS0j7j7DHJR0GTFrUZPUU6loZhbsVZgTh0N+Qdnw==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.7.4.tgz",
"integrity": "sha512-jBUkiqLKvUWpv9GLSuHUFYdmHg0ujC1JEYoZUfeOOfNydZXp1sXObgyPatpcwjWgsdBGsagWW0cdJpX/DO2jMw==",
"dev": true,
"requires": {
"@babel/helper-create-regexp-features-plugin": "^7.8.3"
"@babel/helper-create-regexp-features-plugin": "^7.7.4"
}
},
"@babel/plugin-transform-new-target": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.8.3.tgz",
"integrity": "sha512-QuSGysibQpyxexRyui2vca+Cmbljo8bcRckgzYV4kRIsHpVeyeC3JDO63pY+xFZ6bWOBn7pfKZTqV4o/ix9sFw==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.7.4.tgz",
"integrity": "sha512-CnPRiNtOG1vRodnsyGX37bHQleHE14B9dnnlgSeEs3ek3fHN1A1SScglTCg1sfbe7sRQ2BUcpgpTpWSfMKz3gg==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.3"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-transform-object-super": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.8.3.tgz",
"integrity": "sha512-57FXk+gItG/GejofIyLIgBKTas4+pEU47IXKDBWFTxdPd7F80H8zybyAY7UoblVfBhBGs2EKM+bJUu2+iUYPDQ==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.7.4.tgz",
"integrity": "sha512-ho+dAEhC2aRnff2JCA0SAK7V2R62zJd/7dmtoe7MHcso4C2mS+vZjn1Pb1pCVZvJs1mgsvv5+7sT+m3Bysb6eg==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.3",
"@babel/helper-replace-supers": "^7.8.3"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/helper-replace-supers": "^7.7.4"
}
},
"@babel/plugin-transform-parameters": {
"version": "7.8.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.8.4.tgz",
"integrity": "sha512-IsS3oTxeTsZlE5KqzTbcC2sV0P9pXdec53SU+Yxv7o/6dvGM5AkTotQKhoSffhNgZ/dftsSiOoxy7evCYJXzVA==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.7.4.tgz",
"integrity": "sha512-VJwhVePWPa0DqE9vcfptaJSzNDKrWU/4FbYCjZERtmqEs05g3UMXnYMZoXja7JAJ7Y7sPZipwm/pGApZt7wHlw==",
"dev": true,
"requires": {
"@babel/helper-call-delegate": "^7.8.3",
"@babel/helper-get-function-arity": "^7.8.3",
"@babel/helper-plugin-utils": "^7.8.3"
},
"dependencies": {
"@babel/helper-get-function-arity": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz",
"integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==",
"dev": true,
"requires": {
"@babel/types": "^7.8.3"
}
},
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
},
"@babel/types": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz",
"integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==",
"dev": true,
"requires": {
"esutils": "^2.0.2",
"lodash": "^4.17.13",
"to-fast-properties": "^2.0.0"
}
}
"@babel/helper-call-delegate": "^7.7.4",
"@babel/helper-get-function-arity": "^7.7.4",
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-transform-property-literals": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.8.3.tgz",
"integrity": "sha512-uGiiXAZMqEoQhRWMK17VospMZh5sXWg+dlh2soffpkAl96KAm+WZuJfa6lcELotSRmooLqg0MWdH6UUq85nmmg==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.7.4.tgz",
"integrity": "sha512-MatJhlC4iHsIskWYyawl53KuHrt+kALSADLQQ/HkhTjX954fkxIEh4q5slL4oRAnsm/eDoZ4q0CIZpcqBuxhJQ==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.3"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-transform-react-constant-elements": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.8.3.tgz",
"integrity": "sha512-glrzN2U+egwRfkNFtL34xIBYTxbbUF2qJTP8HD3qETBBqzAWSeNB821X0GjU06+dNpq/UyCIjI72FmGE5NNkQQ==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.7.4.tgz",
"integrity": "sha512-U6XkHZ8RnmeEb8jBUOpeo6oFka5RhLgxAVvK4/fBbwoYlsHQYLb8I37ymTPDVsrWjqb94+hueuWQA/1OAA4rAQ==",
"dev": true,
"requires": {
"@babel/helper-annotate-as-pure": "^7.8.3",
"@babel/helper-plugin-utils": "^7.8.3"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-annotate-as-pure": "^7.7.4",
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-transform-react-display-name": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.8.3.tgz",
"integrity": "sha512-3Jy/PCw8Fe6uBKtEgz3M82ljt+lTg+xJaM4og+eyu83qLT87ZUSckn0wy7r31jflURWLO83TW6Ylf7lyXj3m5A==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.7.4.tgz",
"integrity": "sha512-sBbIvqYkthai0X0vkD2xsAwluBp+LtNHH+/V4a5ydifmTtb8KOVOlrMIk/MYmIc4uTYDnjZUHQildYNo36SRJw==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.3"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-transform-react-jsx": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.8.3.tgz",
"integrity": "sha512-r0h+mUiyL595ikykci+fbwm9YzmuOrUBi0b+FDIKmi3fPQyFokWVEMJnRWHJPPQEjyFJyna9WZC6Viv6UHSv1g==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.7.4.tgz",
"integrity": "sha512-LixU4BS95ZTEAZdPaIuyg/k8FiiqN9laQ0dMHB4MlpydHY53uQdWCUrwjLr5o6ilS6fAgZey4Q14XBjl5tL6xw==",
"dev": true,
"requires": {
"@babel/helper-builder-react-jsx": "^7.8.3",
"@babel/helper-plugin-utils": "^7.8.3",
"@babel/plugin-syntax-jsx": "^7.8.3"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-builder-react-jsx": "^7.7.4",
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/plugin-syntax-jsx": "^7.7.4"
}
},
"@babel/plugin-transform-react-jsx-self": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.8.3.tgz",
"integrity": "sha512-01OT7s5oa0XTLf2I8XGsL8+KqV9lx3EZV+jxn/L2LQ97CGKila2YMroTkCEIE0HV/FF7CMSRsIAybopdN9NTdg==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.7.4.tgz",
"integrity": "sha512-PWYjSfqrO273mc1pKCRTIJXyqfc9vWYBax88yIhQb+bpw3XChVC7VWS4VwRVs63wFHKxizvGSd00XEr+YB9Q2A==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.3",
"@babel/plugin-syntax-jsx": "^7.8.3"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/plugin-syntax-jsx": "^7.7.4"
}
},
"@babel/plugin-transform-react-jsx-source": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.8.3.tgz",
"integrity": "sha512-PLMgdMGuVDtRS/SzjNEQYUT8f4z1xb2BAT54vM1X5efkVuYBf5WyGUMbpmARcfq3NaglIwz08UVQK4HHHbC6ag==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.7.4.tgz",
"integrity": "sha512-5ZU9FnPhqtHsOXxutRtXZAzoEJwDaP32QcobbMP1/qt7NYcsCNK8XgzJcJfoEr/ZnzVvUNInNjIW22Z6I8p9mg==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.3",
"@babel/plugin-syntax-jsx": "^7.8.3"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/plugin-syntax-jsx": "^7.7.4"
}
},
"@babel/plugin-transform-regenerator": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.8.3.tgz",
"integrity": "sha512-qt/kcur/FxrQrzFR432FGZznkVAjiyFtCOANjkAKwCbt465L6ZCiUQh2oMYGU3Wo8LRFJxNDFwWn106S5wVUNA==",
"version": "7.7.5",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.7.5.tgz",
"integrity": "sha512-/8I8tPvX2FkuEyWbjRCt4qTAgZK0DVy8QRguhA524UH48RfGJy94On2ri+dCuwOpcerPRl9O4ebQkRcVzIaGBw==",
"dev": true,
"requires": {
"regenerator-transform": "^0.14.0"
}
},
"@babel/plugin-transform-reserved-words": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.8.3.tgz",
"integrity": "sha512-mwMxcycN3omKFDjDQUl+8zyMsBfjRFr0Zn/64I41pmjv4NJuqcYlEtezwYtw9TFd9WR1vN5kiM+O0gMZzO6L0A==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.7.4.tgz",
"integrity": "sha512-OrPiUB5s5XvkCO1lS7D8ZtHcswIC57j62acAnJZKqGGnHP+TIc/ljQSrgdX/QyOTdEK5COAhuc820Hi1q2UgLQ==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.3"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-transform-shorthand-properties": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.8.3.tgz",
"integrity": "sha512-I9DI6Odg0JJwxCHzbzW08ggMdCezoWcuQRz3ptdudgwaHxTjxw5HgdFJmZIkIMlRymL6YiZcped4TTCB0JcC8w==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.7.4.tgz",
"integrity": "sha512-q+suddWRfIcnyG5YiDP58sT65AJDZSUhXQDZE3r04AuqD6d/XLaQPPXSBzP2zGerkgBivqtQm9XKGLuHqBID6Q==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.3"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-transform-spread": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.8.3.tgz",
"integrity": "sha512-CkuTU9mbmAoFOI1tklFWYYbzX5qCIZVXPVy0jpXgGwkplCndQAa58s2jr66fTeQnA64bDox0HL4U56CFYoyC7g==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.7.4.tgz",
"integrity": "sha512-8OSs0FLe5/80cndziPlg4R0K6HcWSM0zyNhHhLsmw/Nc5MaA49cAsnoJ/t/YZf8qkG7fD+UjTRaApVDB526d7Q==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.3"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-transform-sticky-regex": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.8.3.tgz",
"integrity": "sha512-9Spq0vGCD5Bb4Z/ZXXSK5wbbLFMG085qd2vhL1JYu1WcQ5bXqZBAYRzU1d+p79GcHs2szYv5pVQCX13QgldaWw==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.7.4.tgz",
"integrity": "sha512-Ls2NASyL6qtVe1H1hXts9yuEeONV2TJZmplLONkMPUG158CtmnrzW5Q5teibM5UVOFjG0D3IC5mzXR6pPpUY7A==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.3",
"@babel/helper-regex": "^7.8.3"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/helper-regex": "^7.0.0"
}
},
"@babel/plugin-transform-template-literals": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.8.3.tgz",
"integrity": "sha512-820QBtykIQOLFT8NZOcTRJ1UNuztIELe4p9DCgvj4NK+PwluSJ49we7s9FB1HIGNIYT7wFUJ0ar2QpCDj0escQ==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.7.4.tgz",
"integrity": "sha512-sA+KxLwF3QwGj5abMHkHgshp9+rRz+oY9uoRil4CyLtgEuE/88dpkeWgNk5qKVsJE9iSfly3nvHapdRiIS2wnQ==",
"dev": true,
"requires": {
"@babel/helper-annotate-as-pure": "^7.8.3",
"@babel/helper-plugin-utils": "^7.8.3"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-annotate-as-pure": "^7.7.4",
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-transform-typeof-symbol": {
"version": "7.8.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.8.4.tgz",
"integrity": "sha512-2QKyfjGdvuNfHsb7qnBBlKclbD4CfshH2KvDabiijLMGXPHJXGxtDzwIF7bQP+T0ysw8fYTtxPafgfs/c1Lrqg==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.7.4.tgz",
"integrity": "sha512-KQPUQ/7mqe2m0B8VecdyaW5XcQYaePyl9R7IsKd+irzj6jvbhoGnRE+M0aNkyAzI07VfUQ9266L5xMARitV3wg==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.3"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-transform-unicode-regex": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.8.3.tgz",
"integrity": "sha512-+ufgJjYdmWfSQ+6NS9VGUR2ns8cjJjYbrbi11mZBTaWm+Fui/ncTLFF28Ei1okavY+xkojGr1eJxNsWYeA5aZw==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.7.4.tgz",
"integrity": "sha512-N77UUIV+WCvE+5yHw+oks3m18/umd7y392Zv7mYTpFqHtkpcc+QUz+gLJNTWVlWROIWeLqY0f3OjZxV5TcXnRw==",
"dev": true,
"requires": {
"@babel/helper-create-regexp-features-plugin": "^7.8.3",
"@babel/helper-plugin-utils": "^7.8.3"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
"dev": true
}
"@babel/helper-create-regexp-features-plugin": "^7.7.4",
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/preset-env": {
@@ -2444,16 +936,6 @@
}
}
},
"@babel/runtime-corejs3": {
"version": "7.8.4",
"resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.8.4.tgz",
"integrity": "sha512-+wpLqy5+fbQhvbllvlJEVRIpYj+COUWnnsm+I4jZlA8Lo7/MJmBhGTCHyk1/RWfOqBRJ2MbadddG6QltTKTlrg==",
"dev": true,
"requires": {
"core-js-pure": "^3.0.0",
"regenerator-runtime": "^0.13.2"
}
},
"@babel/template": {
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.4.tgz",
@@ -2529,20 +1011,14 @@
}
},
"@cospired/i18n-iso-languages": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/@cospired/i18n-iso-languages/-/i18n-iso-languages-2.1.1.tgz",
"integrity": "sha512-dmlPmVw51tQzCJkYvtWWXxuvsAkNvCmUnvjMWyo7Qd318YeEZalCUInUgdhKU985gk2wkITtdakPYqk5GrJ99A=="
},
"@edx/eslint-config": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/@edx/eslint-config/-/eslint-config-1.1.4.tgz",
"integrity": "sha512-CKPvyEnOGKWT15VNUmyzhqU3GxVkrCzUekI6XxdbF21oU9bICsHh/rXTtLDdz0EfzK5XvYAhk1OmCu47o6nG8A==",
"dev": true
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@cospired/i18n-iso-languages/-/i18n-iso-languages-2.1.0.tgz",
"integrity": "sha512-r+bqdtVTkO8R07JiBxEc7ckbkXgeIP/X51MxqxODv9gZovc/MBDS6uJVCHg+mtJuldwvSD6L0XF5RzH6qyAacQ=="
},
"@edx/frontend-build": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@edx/frontend-build/-/frontend-build-3.0.0.tgz",
"integrity": "sha512-vYsDROEEgN2Ko2aPvWUQudhaNR4B4Mv57IJf8hVdF5WqQBvJ7JIddJjQV2Wng2kMjhlqkGbof/BPeVSsr3RugQ==",
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/@edx/frontend-build/-/frontend-build-2.0.5.tgz",
"integrity": "sha512-3m+fKAkYliVz9QKuU4xkU4dGu5XqfSJuwYU6aH+pDBtaVj0+wz6srbei6iPoNx9A96rVwJU4aIqDwzmrlx3zgQ==",
"dev": true,
"requires": {
"@babel/cli": "7.6.0",
@@ -2552,7 +1028,6 @@
"@babel/plugin-syntax-dynamic-import": "7.2.0",
"@babel/preset-env": "7.6.0",
"@babel/preset-react": "7.0.0",
"@edx/eslint-config": "1.1.4",
"@svgr/webpack": "4.3.2",
"autoprefixer": "9.6.1",
"babel-eslint": "10.0.3",
@@ -2567,12 +1042,8 @@
"cssnano": "4.1.10",
"dotenv": "8.1.0",
"dotenv-webpack": "1.7.0",
"eslint": "6.8.0",
"eslint-config-airbnb": "18.0.1",
"eslint-plugin-import": "2.20.0",
"eslint-plugin-jsx-a11y": "6.2.3",
"eslint-plugin-react": "7.18.0",
"eslint-plugin-react-hooks": "1.7.0",
"eslint": "6.4.0",
"eslint-config-edx": "4.0.4",
"file-loader": "4.2.0",
"glob": "7.1.4",
"html-webpack-harddisk-plugin": "1.0.1",
@@ -2584,7 +1055,7 @@
"lodash.defaultsdeep": "4.6.1",
"mini-css-extract-plugin": "0.8.0",
"new-relic-source-map-webpack-plugin": "1.2.0",
"node-sass": "4.13.1",
"node-sass": "4.12.0",
"postcss-loader": "3.0.0",
"postcss-rtl": "1.5.0",
"react-dev-utils": "9.0.3",
@@ -2665,13 +1136,13 @@
}
},
"@edx/frontend-platform": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/@edx/frontend-platform/-/frontend-platform-1.3.1.tgz",
"integrity": "sha512-RAJ6IciIX+ZwXhlBfxOOB0sjNNpBQaN/eDLsgztL9MxEmuAvQtbvQBBJAum6qsVZpKzOZYhtRYFyWoHTuyzFZA==",
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/@edx/frontend-platform/-/frontend-platform-1.1.11.tgz",
"integrity": "sha512-Nx1nj/WSZ6ELUUOyjAWfHVTJIkWt7MUhN8cHKCwrnvNcXsAAqKkG3ZiLWErmdg+asfvXcn6E6Ipzej6E7t91PA==",
"requires": {
"@cospired/i18n-iso-languages": "2.1.1",
"@cospired/i18n-iso-languages": "2.1.0",
"axios": "0.18.1",
"form-urlencoded": "4.1.3",
"form-urlencoded": "4.1.0",
"glob": "7.1.6",
"history": "4.10.1",
"i18n-iso-countries": "4.3.1",
@@ -2682,7 +1153,7 @@
"lodash.snakecase": "4.1.1",
"pubsub-js": "1.7.0",
"react-intl": "2.9.0",
"universal-cookie": "4.0.3"
"universal-cookie": "4.0.2"
}
},
"@edx/paragon": {
@@ -2719,18 +1190,18 @@
}
},
"@formatjs/intl-unified-numberformat": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@formatjs/intl-unified-numberformat/-/intl-unified-numberformat-3.2.0.tgz",
"integrity": "sha512-SZMTV/tR0h7nYhS2x69S7zhHXaBmE0ZTR2OIiakt8W7uYWVgcRhu/LgUeVtGzpwPI2ChcOjNMtX/k6y1M9aDNA==",
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@formatjs/intl-unified-numberformat/-/intl-unified-numberformat-2.2.0.tgz",
"integrity": "sha512-A9ov4uO04pSHG5Iqcrc457hvsq3lz/oWQ3B0I03zbL1rnBC8ttrZEobw3X3k/tWYPXeNJbRtsSbXqzJo55NeBw==",
"dev": true,
"requires": {
"@formatjs/intl-utils": "^2.2.0"
"@formatjs/intl-utils": "^1.6.0"
}
},
"@formatjs/intl-utils": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@formatjs/intl-utils/-/intl-utils-2.2.0.tgz",
"integrity": "sha512-+Az7tR1av1DHZu9668D8uh9atT6vp+FFmEF8BrEssv0OqzpVjpVBGVmcgPzQP8k2PQjVlm/h2w8cTt0knn132w==",
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/@formatjs/intl-utils/-/intl-utils-1.6.0.tgz",
"integrity": "sha512-5D0C4tQgNFJNaJ17BYum0GfAcKNK3oa1VWzgkv/AN7i52fg4r69ZLcpEGpf6tZiX9Qld8CDwTQOeFt6fuOqgVw==",
"dev": true
},
"@fortawesome/fontawesome-common-types": {
@@ -3186,26 +1657,6 @@
"integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==",
"dev": true
},
"@reduxjs/toolkit": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.2.3.tgz",
"integrity": "sha512-CgeZl41Bmz1rFkASt5gA9egCy9YWXzy485EsEXoGd2Xm1o63UQCxfuCLTH+XlTs25WqtGjSmn5H4xu7n86ytYw==",
"requires": {
"immer": "^4.0.1",
"redux": "^4.0.0",
"redux-devtools-extension": "^2.13.8",
"redux-immutable-state-invariant": "^2.1.0",
"redux-thunk": "^2.3.0",
"reselect": "^4.0.0"
},
"dependencies": {
"immer": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/immer/-/immer-4.0.2.tgz",
"integrity": "sha512-Q/tm+yKqnKy4RIBmmtISBlhXuSDrB69e9EKTYiIenIKQkXBQir43w+kN/eGiax3wt1J0O1b2fYcNqLSbEcXA7w=="
}
}
},
"@sindresorhus/is": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz",
@@ -3430,9 +1881,9 @@
"dev": true
},
"@types/node": {
"version": "13.7.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-13.7.0.tgz",
"integrity": "sha512-GnZbirvmqZUzMgkFn70c74OQpTTUcCzlhQliTzYjQMqg+hVKcDnxdL19Ne3UdYzdMA/+W3eb646FWn/ZaT1NfQ==",
"version": "12.12.17",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.17.tgz",
"integrity": "sha512-Is+l3mcHvs47sKy+afn2O1rV4ldZFU7W8101cNlOd+MRbjM4Onida8jSZnJdTe/0Pcf25g9BNIUsuugmE6puHA==",
"dev": true
},
"@types/normalize-package-data": {
@@ -3952,9 +2403,9 @@
"dev": true
},
"aria-query": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz",
"integrity": "sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=",
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-0.7.1.tgz",
"integrity": "sha1-Jsu1r/ZBRLCoJb4YRuCxbPoAsR4=",
"dev": true,
"requires": {
"ast-types-flow": "0.0.7",
@@ -4010,68 +2461,32 @@
"dev": true
},
"array-includes": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz",
"integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==",
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.0.tgz",
"integrity": "sha512-ONOEQoKrvXPKk7Su92Co0YMqYO32FfqJTzkKU9u2UpIXyYZIzLSvpdg4AwvSw4mSUW0czu6inK+zby6Oj6gDjQ==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"es-abstract": "^1.17.0",
"is-string": "^1.0.5"
"es-abstract": "^1.17.0-next.0"
},
"dependencies": {
"es-abstract": {
"version": "1.17.4",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz",
"integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==",
"version": "1.17.0-next.1",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.0-next.1.tgz",
"integrity": "sha512-7MmGr03N7Rnuid6+wyhD9sHNE2n4tFSwExnU2lQl3lIo2ShXWGePY80zYaoMOmILWv57H0amMjZGHNzzGG70Rw==",
"dev": true,
"requires": {
"es-to-primitive": "^1.2.1",
"function-bind": "^1.1.1",
"has": "^1.0.3",
"has-symbols": "^1.0.1",
"is-callable": "^1.1.5",
"is-regex": "^1.0.5",
"is-callable": "^1.1.4",
"is-regex": "^1.0.4",
"object-inspect": "^1.7.0",
"object-keys": "^1.1.1",
"object.assign": "^4.1.0",
"string.prototype.trimleft": "^2.1.1",
"string.prototype.trimright": "^2.1.1"
}
},
"is-callable": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz",
"integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==",
"dev": true
},
"is-regex": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
"integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
"dev": true,
"requires": {
"has": "^1.0.3"
}
},
"string.prototype.trimleft": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz",
"integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"function-bind": "^1.1.1"
}
},
"string.prototype.trimright": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz",
"integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"function-bind": "^1.1.1"
"string.prototype.trimleft": "^2.1.0",
"string.prototype.trimright": "^2.1.0"
}
}
}
@@ -4128,57 +2543,22 @@
},
"dependencies": {
"es-abstract": {
"version": "1.17.4",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz",
"integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==",
"version": "1.17.0-next.1",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.0-next.1.tgz",
"integrity": "sha512-7MmGr03N7Rnuid6+wyhD9sHNE2n4tFSwExnU2lQl3lIo2ShXWGePY80zYaoMOmILWv57H0amMjZGHNzzGG70Rw==",
"dev": true,
"requires": {
"es-to-primitive": "^1.2.1",
"function-bind": "^1.1.1",
"has": "^1.0.3",
"has-symbols": "^1.0.1",
"is-callable": "^1.1.5",
"is-regex": "^1.0.5",
"is-callable": "^1.1.4",
"is-regex": "^1.0.4",
"object-inspect": "^1.7.0",
"object-keys": "^1.1.1",
"object.assign": "^4.1.0",
"string.prototype.trimleft": "^2.1.1",
"string.prototype.trimright": "^2.1.1"
}
},
"is-callable": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz",
"integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==",
"dev": true
},
"is-regex": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
"integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
"dev": true,
"requires": {
"has": "^1.0.3"
}
},
"string.prototype.trimleft": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz",
"integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"function-bind": "^1.1.1"
}
},
"string.prototype.trimright": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz",
"integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"function-bind": "^1.1.1"
"string.prototype.trimleft": "^2.1.0",
"string.prototype.trimright": "^2.1.0"
}
}
}
@@ -4323,13 +2703,12 @@
}
},
"axobject-query": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.1.1.tgz",
"integrity": "sha512-lF98xa/yvy6j3fBHAgQXIYl+J4eZadOSqsPojemUqClzNbBV38wWGpUbQbVEyf4eUF5yF7eHmGgGA2JiHyjeqw==",
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-0.1.0.tgz",
"integrity": "sha1-YvWdvFnJ+SQnWco0mWDnov48NsA=",
"dev": true,
"requires": {
"@babel/runtime": "^7.7.4",
"@babel/runtime-corejs3": "^7.7.4"
"ast-types-flow": "0.0.7"
}
},
"babel-code-frame": {
@@ -4484,12 +2863,12 @@
},
"dependencies": {
"intl-messageformat-parser": {
"version": "3.6.4",
"resolved": "https://registry.npmjs.org/intl-messageformat-parser/-/intl-messageformat-parser-3.6.4.tgz",
"integrity": "sha512-RgPGwue0mJtoX2Ax8EmMzJzttxjnva7gx0Q7mKJ4oALrTZvtmCeAw5Msz2PcjW4dtCh/h7vN/8GJCxZO1uv+OA==",
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/intl-messageformat-parser/-/intl-messageformat-parser-3.5.1.tgz",
"integrity": "sha512-aCUjbLCZYhWJzC5gJiXKYR+OCE8rIegRBsjm1irJSH0AmeC7dIOp3nzOCc84BcyFX5baoXJfijV6SWqYUrN27w==",
"dev": true,
"requires": {
"@formatjs/intl-unified-numberformat": "^3.2.0"
"@formatjs/intl-unified-numberformat": "^2.2.0"
}
}
}
@@ -4974,9 +3353,9 @@
"dev": true
},
"readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
"core-util-is": "~1.0.0",
@@ -5243,14 +3622,14 @@
}
},
"browserslist": {
"version": "4.8.6",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.8.6.tgz",
"integrity": "sha512-ZHao85gf0eZ0ESxLfCp73GG9O/VTytYDIkIiZDlURppLTI9wErSM/5yAKEq6rcUdxBLjMELmrYUJGg5sxGKMHg==",
"version": "4.8.2",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.8.2.tgz",
"integrity": "sha512-+M4oeaTplPm/f1pXDw84YohEv7B1i/2Aisei8s4s6k3QsoSHa7i5sz8u/cGQkkatCPxMASKxPualR4wwYgVboA==",
"dev": true,
"requires": {
"caniuse-lite": "^1.0.30001023",
"electron-to-chromium": "^1.3.341",
"node-releases": "^1.1.47"
"caniuse-lite": "^1.0.30001015",
"electron-to-chromium": "^1.3.322",
"node-releases": "^1.1.42"
}
},
"bser": {
@@ -5513,9 +3892,9 @@
}
},
"caniuse-lite": {
"version": "1.0.30001025",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001025.tgz",
"integrity": "sha512-SKyFdHYfXUZf5V85+PJgLYyit27q4wgvZuf8QTOk1osbypcROihMBlx9GRar2/pIcKH2r4OehdlBr9x6PXetAQ==",
"version": "1.0.30001015",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001015.tgz",
"integrity": "sha512-/xL2AbW/XWHNu1gnIrO8UitBGoFthcsDgU9VLK1/dpsoxbaD5LscHozKze05R6WLsBvLhqv78dAPozMFQBYLbQ==",
"dev": true
},
"caporal": {
@@ -5697,6 +4076,12 @@
"safe-buffer": "^5.0.1"
}
},
"circular-json": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz",
"integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==",
"dev": true
},
"class-utils": {
"version": "0.3.6",
"resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
@@ -5726,9 +4111,9 @@
"integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q=="
},
"clean-css": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz",
"integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==",
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz",
"integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==",
"dev": true,
"requires": {
"source-map": "~0.6.0"
@@ -5744,12 +4129,12 @@
}
},
"cli-cursor": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
"integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
"integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
"dev": true,
"requires": {
"restore-cursor": "^3.1.0"
"restore-cursor": "^2.0.0"
}
},
"cli-table3": {
@@ -5969,20 +4354,12 @@
}
},
"compressible": {
"version": "2.0.18",
"resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
"integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==",
"version": "2.0.17",
"resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.17.tgz",
"integrity": "sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw==",
"dev": true,
"requires": {
"mime-db": ">= 1.43.0 < 2"
},
"dependencies": {
"mime-db": {
"version": "1.43.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz",
"integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==",
"dev": true
}
"mime-db": ">= 1.40.0 < 2"
}
},
"compression": {
@@ -6088,12 +4465,6 @@
"proto-list": "~1.2.1"
}
},
"confusing-browser-globals": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz",
"integrity": "sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw==",
"dev": true
},
"connect-history-api-fallback": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz",
@@ -6233,29 +4604,23 @@
"integrity": "sha512-hIE5dXkRzRvnZ5vhkRfQxUvDxQZmD9oueA08jDYRBKJHx+VIl/Pne/e0A4x9LObEEthC/TqiZybUoNM4tRgnKg=="
},
"core-js-compat": {
"version": "3.6.4",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.4.tgz",
"integrity": "sha512-zAa3IZPvsJ0slViBQ2z+vgyyTuhd3MFn1rBQjZSKVEgB0UMYhUkCj9jJUVPgGTGqWvsBVmfnruXgTcNyTlEiSA==",
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.5.0.tgz",
"integrity": "sha512-E7iJB72svRjJTnm9HDvujzNVMCm3ZcDYEedkJ/sDTNsy/0yooCd9Cg7GSzE7b4e0LfIkjijdB1tqg0pGwxWeWg==",
"dev": true,
"requires": {
"browserslist": "^4.8.3",
"semver": "7.0.0"
"browserslist": "^4.8.2",
"semver": "^6.3.0"
},
"dependencies": {
"semver": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
"integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==",
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
}
}
},
"core-js-pure": {
"version": "3.6.4",
"resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.4.tgz",
"integrity": "sha512-epIhRLkXdgv32xIUFaaAry2wdxZYBi6bgM7cB136dzzXXa+dFyRLTZeLUJxnd8ShrmyVXBub63n2NHo2JAt8Cw==",
"dev": true
},
"core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
@@ -6392,9 +4757,9 @@
},
"dependencies": {
"schema-utils": {
"version": "2.6.4",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.4.tgz",
"integrity": "sha512-VNjcaUxVnEeun6B2fiiUDjXXBtD4ZSH7pdbfIu1pOFwgptDPLMo/z9jr4sUfsjFVPqDCEin/F7IYlq7/E6yDbQ==",
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.1.tgz",
"integrity": "sha512-0WXHDs1VDJyo+Zqs9TKLKyD/h7yDpHUhEFsM2CzkICFdoX1av+GBq/J2xRTFfsQO5kBfhZzANf2VcIm84jqDbg==",
"dev": true,
"requires": {
"ajv": "^6.10.2",
@@ -6556,9 +4921,9 @@
}
},
"csstype": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.9.tgz",
"integrity": "sha512-xz39Sb4+OaTsULgUERcCk+TJj8ylkL4aSVDQiX/ksxbELSqwkgt4d4RD7fovIdgJGSuNYqwZEiVjYY5l0ask+Q=="
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.7.tgz",
"integrity": "sha512-9Mcn9sFbGBAdmimWb2gLVDtFJzeKtDGIr76TUqmjZrw9LFXBMSU70lcs+C0/7fyCd6iBDqmksUcCOUIkisPHsQ=="
},
"currently-unhandled": {
"version": "0.4.1",
@@ -6603,9 +4968,9 @@
}
},
"damerau-levenshtein": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz",
"integrity": "sha512-JVrozIeElnj3QzfUIt8tB8YMluBJom4Vw9qTPpjGYQ9fYlB3D/rb6OordUxf3xeFB35LKWs0xqcO5U6ySvBtug==",
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.5.tgz",
"integrity": "sha512-CBCRqFnpu715iPmw1KrdOrzRqbdFwQTwAWyyyYS42+iAgHCuXZ+/TdMgQkUENPomxEz9z1BEzuQU2Xw0kUuAgA==",
"dev": true
},
"dashdash": {
@@ -7159,9 +5524,9 @@
"dev": true
},
"dotenv-defaults": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/dotenv-defaults/-/dotenv-defaults-1.1.1.tgz",
"integrity": "sha512-6fPRo9o/3MxKvmRZBD3oNFdxODdhJtIy1zcJeUSCs6HCy4tarUpd+G67UTU9tF6OWXeSPqsm4fPAB+2eY9Rt9Q==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/dotenv-defaults/-/dotenv-defaults-1.0.2.tgz",
"integrity": "sha512-iXFvHtXl/hZPiFj++1hBg4lbKwGM+t/GlvELDnRtOFdjXyWP7mubkVr+eZGWG62kdsbulXAef6v/j6kiWc/xGA==",
"dev": true,
"requires": {
"dotenv": "^6.2.0"
@@ -7257,9 +5622,9 @@
"dev": true
},
"readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
"core-util-is": "~1.0.0",
@@ -7311,9 +5676,9 @@
"dev": true
},
"electron-to-chromium": {
"version": "1.3.345",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.345.tgz",
"integrity": "sha512-f8nx53+Z9Y+SPWGg3YdHrbYYfIJAtbUjpFfW4X1RwTZ94iUG7geg9tV8HqzAXX7XTNgyWgAFvce4yce8ZKxKmg==",
"version": "1.3.322",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.322.tgz",
"integrity": "sha512-Tc8JQEfGQ1MzfSzI/bTlSr7btJv/FFO7Yh6tanqVmIWOuNCu6/D1MilIEgLtmWqIrsv+o4IjpLAhgMBr/ncNAA==",
"dev": true
},
"elliptic": {
@@ -7399,9 +5764,9 @@
}
},
"readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
"core-util-is": "~1.0.0",
@@ -7579,9 +5944,9 @@
}
},
"eslint": {
"version": "6.8.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz",
"integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==",
"version": "6.4.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-6.4.0.tgz",
"integrity": "sha512-WTVEzK3lSFoXUovDHEbkJqCVPEPwbhCq4trDktNI6ygs7aO41d4cDT0JFAT5MivzZeVLWlg7vHL+bgrQv/t3vA==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
@@ -7591,19 +5956,19 @@
"debug": "^4.0.1",
"doctrine": "^3.0.0",
"eslint-scope": "^5.0.0",
"eslint-utils": "^1.4.3",
"eslint-utils": "^1.4.2",
"eslint-visitor-keys": "^1.1.0",
"espree": "^6.1.2",
"espree": "^6.1.1",
"esquery": "^1.0.1",
"esutils": "^2.0.2",
"file-entry-cache": "^5.0.1",
"functional-red-black-tree": "^1.0.1",
"glob-parent": "^5.0.0",
"globals": "^12.1.0",
"globals": "^11.7.0",
"ignore": "^4.0.6",
"import-fresh": "^3.0.0",
"imurmurhash": "^0.1.4",
"inquirer": "^7.0.0",
"inquirer": "^6.4.1",
"is-glob": "^4.0.0",
"js-yaml": "^3.13.1",
"json-stable-stringify-without-jsonify": "^1.0.1",
@@ -7612,7 +5977,7 @@
"minimatch": "^3.0.4",
"mkdirp": "^0.5.1",
"natural-compare": "^1.4.0",
"optionator": "^0.8.3",
"optionator": "^0.8.2",
"progress": "^2.0.0",
"regexpp": "^2.0.1",
"semver": "^6.1.2",
@@ -7641,15 +6006,6 @@
"is-glob": "^4.0.1"
}
},
"globals": {
"version": "12.3.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-12.3.0.tgz",
"integrity": "sha512-wAfjdLgFsPZsklLJvOBUBmzYE8/CwhEqSBEMRXA3qxIiNtyqvjYurAtIfDh6chlEPUfmTY3MnZh5Hfh4q0UlIw==",
"dev": true,
"requires": {
"type-fest": "^0.8.1"
}
},
"ignore": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
@@ -7683,45 +6039,329 @@
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
},
"type-fest": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
"dev": true
}
}
},
"eslint-config-airbnb": {
"version": "18.0.1",
"resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-18.0.1.tgz",
"integrity": "sha512-hLb/ccvW4grVhvd6CT83bECacc+s4Z3/AEyWQdIT2KeTsG9dR7nx1gs7Iw4tDmGKozCNHFn4yZmRm3Tgy+XxyQ==",
"version": "16.1.0",
"resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-16.1.0.tgz",
"integrity": "sha512-zLyOhVWhzB/jwbz7IPSbkUuj7X2ox4PHXTcZkEmDqTvd0baJmJyuxlFPDlZOE/Y5bC+HQRaEkT3FoHo9wIdRiw==",
"dev": true,
"requires": {
"eslint-config-airbnb-base": "^14.0.0",
"object.assign": "^4.1.0",
"object.entries": "^1.1.0"
"eslint-config-airbnb-base": "^12.1.0"
}
},
"eslint-config-airbnb-base": {
"version": "14.0.0",
"resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.0.0.tgz",
"integrity": "sha512-2IDHobw97upExLmsebhtfoD3NAKhV4H0CJWP3Uprd/uk+cHuWYOczPVxQ8PxLFUAw7o3Th1RAU8u1DoUpr+cMA==",
"version": "12.1.0",
"resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-12.1.0.tgz",
"integrity": "sha512-/vjm0Px5ZCpmJqnjIzcFb9TKZrKWz0gnuG/7Gfkt0Db1ELJR51xkZth+t14rYdqWgX836XbuxtArbIHlVhbLBA==",
"dev": true,
"requires": {
"confusing-browser-globals": "^1.0.7",
"object.assign": "^4.1.0",
"object.entries": "^1.1.0"
"eslint-restricted-globals": "^0.1.1"
}
},
"eslint-config-edx": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/eslint-config-edx/-/eslint-config-edx-4.0.4.tgz",
"integrity": "sha512-4xm13P14kcm3IppkjL8X3HDxLgA064l3F50sy7z8ioyB4kDLRepSSXhyDHR8vHDd46yztmnuIPXbEEgVNOL4xg==",
"dev": true,
"requires": {
"eslint": "^4.5.0",
"eslint-config-airbnb": "^16.1.0",
"eslint-plugin-dollar-sign": "^1.0.1",
"eslint-plugin-import": "^2.8.0",
"eslint-plugin-jsx-a11y": "6.0.3",
"eslint-plugin-react": "^7.5.1"
},
"dependencies": {
"acorn": {
"version": "5.7.3",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz",
"integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==",
"dev": true
},
"acorn-jsx": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz",
"integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=",
"dev": true,
"requires": {
"acorn": "^3.0.4"
},
"dependencies": {
"acorn": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
"integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=",
"dev": true
}
}
},
"ajv": {
"version": "5.5.2",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
"integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
"dev": true,
"requires": {
"co": "^4.6.0",
"fast-deep-equal": "^1.0.0",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.3.0"
}
},
"ajv-keywords": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz",
"integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=",
"dev": true
},
"chardet": {
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz",
"integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=",
"dev": true
},
"cross-spawn": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
"integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
"dev": true,
"requires": {
"lru-cache": "^4.0.1",
"shebang-command": "^1.2.0",
"which": "^1.2.9"
}
},
"doctrine": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
"integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
"dev": true,
"requires": {
"esutils": "^2.0.2"
}
},
"eslint": {
"version": "4.19.1",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz",
"integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==",
"dev": true,
"requires": {
"ajv": "^5.3.0",
"babel-code-frame": "^6.22.0",
"chalk": "^2.1.0",
"concat-stream": "^1.6.0",
"cross-spawn": "^5.1.0",
"debug": "^3.1.0",
"doctrine": "^2.1.0",
"eslint-scope": "^3.7.1",
"eslint-visitor-keys": "^1.0.0",
"espree": "^3.5.4",
"esquery": "^1.0.0",
"esutils": "^2.0.2",
"file-entry-cache": "^2.0.0",
"functional-red-black-tree": "^1.0.1",
"glob": "^7.1.2",
"globals": "^11.0.1",
"ignore": "^3.3.3",
"imurmurhash": "^0.1.4",
"inquirer": "^3.0.6",
"is-resolvable": "^1.0.0",
"js-yaml": "^3.9.1",
"json-stable-stringify-without-jsonify": "^1.0.1",
"levn": "^0.3.0",
"lodash": "^4.17.4",
"minimatch": "^3.0.2",
"mkdirp": "^0.5.1",
"natural-compare": "^1.4.0",
"optionator": "^0.8.2",
"path-is-inside": "^1.0.2",
"pluralize": "^7.0.0",
"progress": "^2.0.0",
"regexpp": "^1.0.1",
"require-uncached": "^1.0.3",
"semver": "^5.3.0",
"strip-ansi": "^4.0.0",
"strip-json-comments": "~2.0.1",
"table": "4.0.2",
"text-table": "~0.2.0"
}
},
"eslint-scope": {
"version": "3.7.3",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz",
"integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==",
"dev": true,
"requires": {
"esrecurse": "^4.1.0",
"estraverse": "^4.1.1"
}
},
"espree": {
"version": "3.5.4",
"resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz",
"integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==",
"dev": true,
"requires": {
"acorn": "^5.5.0",
"acorn-jsx": "^3.0.0"
}
},
"external-editor": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz",
"integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==",
"dev": true,
"requires": {
"chardet": "^0.4.0",
"iconv-lite": "^0.4.17",
"tmp": "^0.0.33"
}
},
"fast-deep-equal": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
"integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=",
"dev": true
},
"file-entry-cache": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz",
"integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=",
"dev": true,
"requires": {
"flat-cache": "^1.2.1",
"object-assign": "^4.0.1"
}
},
"flat-cache": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz",
"integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==",
"dev": true,
"requires": {
"circular-json": "^0.3.1",
"graceful-fs": "^4.1.2",
"rimraf": "~2.6.2",
"write": "^0.2.1"
}
},
"inquirer": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz",
"integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==",
"dev": true,
"requires": {
"ansi-escapes": "^3.0.0",
"chalk": "^2.0.0",
"cli-cursor": "^2.1.0",
"cli-width": "^2.0.0",
"external-editor": "^2.0.4",
"figures": "^2.0.0",
"lodash": "^4.3.0",
"mute-stream": "0.0.7",
"run-async": "^2.2.0",
"rx-lite": "^4.0.8",
"rx-lite-aggregates": "^4.0.8",
"string-width": "^2.1.0",
"strip-ansi": "^4.0.0",
"through": "^2.3.6"
}
},
"json-schema-traverse": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
"integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=",
"dev": true
},
"lru-cache": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
"integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
"dev": true,
"requires": {
"pseudomap": "^1.0.2",
"yallist": "^2.1.2"
}
},
"regexpp": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz",
"integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==",
"dev": true
},
"rimraf": {
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
"integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
"dev": true,
"requires": {
"glob": "^7.1.3"
}
},
"slice-ansi": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz",
"integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==",
"dev": true,
"requires": {
"is-fullwidth-code-point": "^2.0.0"
}
},
"strip-ansi": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
"integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
"dev": true,
"requires": {
"ansi-regex": "^3.0.0"
}
},
"strip-json-comments": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
"dev": true
},
"table": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz",
"integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==",
"dev": true,
"requires": {
"ajv": "^5.2.3",
"ajv-keywords": "^2.1.0",
"chalk": "^2.1.0",
"lodash": "^4.17.4",
"slice-ansi": "1.0.0",
"string-width": "^2.1.1"
}
},
"write": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz",
"integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=",
"dev": true,
"requires": {
"mkdirp": "^0.5.1"
}
},
"yallist": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
"integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
"dev": true
}
}
},
"eslint-import-resolver-node": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz",
"integrity": "sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg==",
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz",
"integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==",
"dev": true,
"requires": {
"debug": "^2.6.9",
"resolve": "^1.13.1"
"resolve": "^1.5.0"
},
"dependencies": {
"debug": {
@@ -7736,9 +6376,9 @@
}
},
"eslint-module-utils": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.5.2.tgz",
"integrity": "sha512-LGScZ/JSlqGKiT8OC+cYRxseMjyqt6QO54nl281CK93unD89ijSeRV6An8Ci/2nvWVKe8K/Tqdm75RQoIOCr+Q==",
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.5.0.tgz",
"integrity": "sha512-kCo8pZaNz2dsAW7nCUjuVoI11EBXXpIzfNxmaoLhXoRDOnqXLC4iSGVRdZPhOitfbdEfMEfKOiENaK6wDPZEGw==",
"dev": true,
"requires": {
"debug": "^2.6.9",
@@ -7808,10 +6448,22 @@
}
}
},
"eslint-plugin-dollar-sign": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/eslint-plugin-dollar-sign/-/eslint-plugin-dollar-sign-1.0.2.tgz",
"integrity": "sha512-AtA5MJpMAh0kKzSx/u7DuDbPRijIZmlt6n75CR8Q3UQ18Fo4QFfYK15lJ8OhXQQUYR7zTMMB2x37KyP3LnAC/g==",
"dev": true
},
"eslint-plugin-eslint-plugin": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-eslint-plugin/-/eslint-plugin-eslint-plugin-2.1.0.tgz",
"integrity": "sha512-kT3A/ZJftt28gbl/Cv04qezb/NQ1dwYIbi8lyf806XMxkus7DvOVCLIfTXMrorp322Pnoez7+zabXH29tADIDg==",
"dev": true
},
"eslint-plugin-import": {
"version": "2.20.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.20.0.tgz",
"integrity": "sha512-NK42oA0mUc8Ngn4kONOPsPB1XhbUvNHqF+g307dPV28aknPoiNnKLFd9em4nkswwepdF5ouieqv5Th/63U7YJQ==",
"version": "2.19.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.19.1.tgz",
"integrity": "sha512-x68131aKoCZlCae7rDXKSAQmbT5DQuManyXo2sK6fJJ0aK5CWAkv6A6HJZGgqC8IhjQxYPgo6/IY4Oz8AFsbBw==",
"dev": true,
"requires": {
"array-includes": "^3.0.3",
@@ -7956,37 +6608,44 @@
}
},
"eslint-plugin-jsx-a11y": {
"version": "6.2.3",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.3.tgz",
"integrity": "sha512-CawzfGt9w83tyuVekn0GDPU9ytYtxyxyFZ3aSWROmnRRFQFT2BiPJd7jvRdzNDi6oLWaS2asMeYSNMjWTV4eNg==",
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.0.3.tgz",
"integrity": "sha1-VFg9GuRCSDFi4EDhPMMYZUZRAOU=",
"dev": true,
"requires": {
"@babel/runtime": "^7.4.5",
"aria-query": "^3.0.0",
"aria-query": "^0.7.0",
"array-includes": "^3.0.3",
"ast-types-flow": "^0.0.7",
"axobject-query": "^2.0.2",
"damerau-levenshtein": "^1.0.4",
"emoji-regex": "^7.0.2",
"has": "^1.0.3",
"jsx-ast-utils": "^2.2.1"
"ast-types-flow": "0.0.7",
"axobject-query": "^0.1.0",
"damerau-levenshtein": "^1.0.0",
"emoji-regex": "^6.1.0",
"jsx-ast-utils": "^2.0.0"
},
"dependencies": {
"emoji-regex": {
"version": "6.5.1",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.5.1.tgz",
"integrity": "sha512-PAHp6TxrCy7MGMFidro8uikr+zlJJKJ/Q6mm2ExZ7HwkyR9lSVFfE3kt36qcwa24BQL7y0G9axycGjK1A/0uNQ==",
"dev": true
}
}
},
"eslint-plugin-react": {
"version": "7.18.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.18.0.tgz",
"integrity": "sha512-p+PGoGeV4SaZRDsXqdj9OWcOrOpZn8gXoGPcIQTzo2IDMbAKhNDnME9myZWqO3Ic4R3YmwAZ1lDjWl2R2hMUVQ==",
"version": "7.17.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.17.0.tgz",
"integrity": "sha512-ODB7yg6lxhBVMeiH1c7E95FLD4E/TwmFjltiU+ethv7KPdCwgiFuOZg9zNRHyufStTDLl/dEFqI2Q1VPmCd78A==",
"dev": true,
"requires": {
"array-includes": "^3.1.1",
"array-includes": "^3.0.3",
"doctrine": "^2.1.0",
"eslint-plugin-eslint-plugin": "^2.1.0",
"has": "^1.0.3",
"jsx-ast-utils": "^2.2.3",
"object.entries": "^1.1.1",
"object.fromentries": "^2.0.2",
"object.values": "^1.1.1",
"object.entries": "^1.1.0",
"object.fromentries": "^2.0.1",
"object.values": "^1.1.0",
"prop-types": "^15.7.2",
"resolve": "^1.14.2"
"resolve": "^1.13.1"
},
"dependencies": {
"doctrine": {
@@ -7997,88 +6656,13 @@
"requires": {
"esutils": "^2.0.2"
}
},
"es-abstract": {
"version": "1.17.4",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz",
"integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==",
"dev": true,
"requires": {
"es-to-primitive": "^1.2.1",
"function-bind": "^1.1.1",
"has": "^1.0.3",
"has-symbols": "^1.0.1",
"is-callable": "^1.1.5",
"is-regex": "^1.0.5",
"object-inspect": "^1.7.0",
"object-keys": "^1.1.1",
"object.assign": "^4.1.0",
"string.prototype.trimleft": "^2.1.1",
"string.prototype.trimright": "^2.1.1"
}
},
"is-callable": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz",
"integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==",
"dev": true
},
"is-regex": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
"integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
"dev": true,
"requires": {
"has": "^1.0.3"
}
},
"object.entries": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.1.tgz",
"integrity": "sha512-ilqR7BgdyZetJutmDPfXCDffGa0/Yzl2ivVNpbx/g4UeWrCdRnFDUBrKJGLhGieRHDATnyZXWBeCb29k9CJysQ==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"es-abstract": "^1.17.0-next.1",
"function-bind": "^1.1.1",
"has": "^1.0.3"
}
},
"resolve": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.0.tgz",
"integrity": "sha512-+hTmAldEGE80U2wJJDC1lebb5jWqvTYAfm3YZ1ckk1gBr0MnCqUKlwK1e+anaFljIl+F5tR5IoZcm4ZDA1zMQw==",
"dev": true,
"requires": {
"path-parse": "^1.0.6"
}
},
"string.prototype.trimleft": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz",
"integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"function-bind": "^1.1.1"
}
},
"string.prototype.trimright": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz",
"integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"function-bind": "^1.1.1"
}
}
}
},
"eslint-plugin-react-hooks": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz",
"integrity": "sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA==",
"eslint-restricted-globals": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz",
"integrity": "sha1-NfDVy8ZMLj7WLpO0saevBbp+1Nc=",
"dev": true
},
"eslint-scope": {
@@ -8166,9 +6750,9 @@
"dev": true
},
"events": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz",
"integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz",
"integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==",
"dev": true
},
"eventsource": {
@@ -8654,9 +7238,9 @@
"dev": true
},
"figures": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/figures/-/figures-3.1.0.tgz",
"integrity": "sha512-ravh8VRXqHuMvZt/d8GblBeqDMkdJMBdv/2KntFH+ra5MXkO7nxNKpzQ3n6QD/2da1kH0aWmNISdvhM7gl2gVg==",
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
"integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
"dev": true,
"requires": {
"escape-string-regexp": "^1.0.5"
@@ -8682,9 +7266,9 @@
},
"dependencies": {
"schema-utils": {
"version": "2.6.4",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.4.tgz",
"integrity": "sha512-VNjcaUxVnEeun6B2fiiUDjXXBtD4ZSH7pdbfIu1pOFwgptDPLMo/z9jr4sUfsjFVPqDCEin/F7IYlq7/E6yDbQ==",
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.1.tgz",
"integrity": "sha512-0WXHDs1VDJyo+Zqs9TKLKyD/h7yDpHUhEFsM2CzkICFdoX1av+GBq/J2xRTFfsQO5kBfhZzANf2VcIm84jqDbg==",
"dev": true,
"requires": {
"ajv": "^6.10.2",
@@ -8875,9 +7459,9 @@
"dev": true
},
"readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
"core-util-is": "~1.0.0",
@@ -8968,9 +7552,9 @@
}
},
"form-urlencoded": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/form-urlencoded/-/form-urlencoded-4.1.3.tgz",
"integrity": "sha512-z0YJtPuq0BSOrErlpj+o1KHTRaOH6LN16043ZVK2Wk5uUGpX308PJ5ZJDtU++ndoZkzASHVclUTD2mb1jHzqlA=="
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/form-urlencoded/-/form-urlencoded-4.1.0.tgz",
"integrity": "sha512-1F/gR6Lx+KX1PtV2l0Gg+PcJ61h5NLNJBgIK4p+L1V958h5bmPi8GD8enlT1a7Sr32EVzea+qOzpO/gl3mOgZA=="
},
"formidable": {
"version": "1.2.1",
@@ -9016,9 +7600,9 @@
"dev": true
},
"readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
"core-util-is": "~1.0.0",
@@ -9089,9 +7673,9 @@
"dev": true
},
"readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
"core-util-is": "~1.0.0",
@@ -9920,9 +8504,9 @@
}
},
"globule": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/globule/-/globule-1.3.0.tgz",
"integrity": "sha512-YlD4kdMqRCQHrhVdonet4TdRtv1/sZKepvoxNT4Nrhrp5HI8XFfc8kFlGlBn2myBo80aGp8Eft259mbcUJhgSg==",
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/globule/-/globule-1.2.1.tgz",
"integrity": "sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==",
"dev": true,
"requires": {
"glob": "~7.1.1",
@@ -10239,9 +8823,9 @@
"dev": true
},
"readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
"core-util-is": "~1.0.0",
@@ -10916,81 +9500,24 @@
"dev": true
},
"inquirer": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.4.tgz",
"integrity": "sha512-Bu5Td5+j11sCkqfqmUTiwv+tWisMtP0L7Q8WrqA2C/BbBhy1YTdFrvjjlrKq8oagA/tLQBski2Gcx/Sqyi2qSQ==",
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz",
"integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==",
"dev": true,
"requires": {
"ansi-escapes": "^4.2.1",
"ansi-escapes": "^3.2.0",
"chalk": "^2.4.2",
"cli-cursor": "^3.1.0",
"cli-cursor": "^2.1.0",
"cli-width": "^2.0.0",
"external-editor": "^3.0.3",
"figures": "^3.0.0",
"lodash": "^4.17.15",
"mute-stream": "0.0.8",
"figures": "^2.0.0",
"lodash": "^4.17.12",
"mute-stream": "0.0.7",
"run-async": "^2.2.0",
"rxjs": "^6.5.3",
"string-width": "^4.1.0",
"rxjs": "^6.4.0",
"string-width": "^2.1.0",
"strip-ansi": "^5.1.0",
"through": "^2.3.6"
},
"dependencies": {
"ansi-escapes": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz",
"integrity": "sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg==",
"dev": true,
"requires": {
"type-fest": "^0.8.1"
}
},
"ansi-regex": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
"dev": true
},
"emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true
},
"is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true
},
"string-width": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
"integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
"dev": true,
"requires": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.0"
},
"dependencies": {
"strip-ansi": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
"dev": true,
"requires": {
"ansi-regex": "^5.0.0"
}
}
}
},
"type-fest": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
"dev": true
}
}
},
"internal-ip": {
@@ -11446,12 +9973,6 @@
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
"dev": true
},
"is-string": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz",
"integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==",
"dev": true
},
"is-svg": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz",
@@ -12179,7 +10700,8 @@
"json-stringify-safe": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
"dev": true
},
"json3": {
"version": "3.3.3",
@@ -12672,6 +11194,12 @@
"p-is-promise": "^2.0.0"
},
"dependencies": {
"mimic-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
"dev": true
},
"p-is-promise": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz",
@@ -12697,9 +11225,9 @@
"dev": true
},
"readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
"core-util-is": "~1.0.0",
@@ -12962,9 +11490,9 @@
}
},
"mimic-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
"integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
"dev": true
},
"mimic-response": {
@@ -13158,9 +11686,9 @@
"dev": true
},
"mute-stream": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
"integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
"integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
"dev": true
},
"nan": {
@@ -13337,9 +11865,9 @@
"dev": true
},
"readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
"core-util-is": "~1.0.0",
@@ -13407,9 +11935,9 @@
}
},
"node-releases": {
"version": "1.1.47",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.47.tgz",
"integrity": "sha512-k4xjVPx5FpwBUj0Gw7uvFOTF4Ep8Hok1I6qjwL3pLfwe7Y0REQSAqOwwv9TWBCUtMHxcXfY4PgRLRozcChvTcA==",
"version": "1.1.42",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.42.tgz",
"integrity": "sha512-OQ/ESmUqGawI2PRX+XIRao44qWYBBfN54ImQYdWVTQqUckuejOg76ysSqDBK8NG3zwySRVnX36JwDQ6x+9GxzA==",
"dev": true,
"requires": {
"semver": "^6.3.0"
@@ -13424,9 +11952,9 @@
}
},
"node-sass": {
"version": "4.13.1",
"resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.13.1.tgz",
"integrity": "sha512-TTWFx+ZhyDx1Biiez2nB0L3YrCZ/8oHagaDalbuBSlqXgUPsdkUSzJsVxeDO9LtPB49+Fh3WQl3slABo6AotNw==",
"version": "4.12.0",
"resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.12.0.tgz",
"integrity": "sha512-A1Iv4oN+Iel6EPv77/HddXErL2a+gZ4uBeZUy+a8O35CFYTXhgA8MgLCWBtwpGZdCvTvQ9d+bQxX/QC36GDPpQ==",
"dev": true,
"requires": {
"async-foreach": "^0.1.3",
@@ -13436,7 +11964,7 @@
"get-stdin": "^4.0.1",
"glob": "^7.0.3",
"in-publish": "^2.0.0",
"lodash": "^4.17.15",
"lodash": "^4.17.11",
"meow": "^3.7.0",
"mkdirp": "^0.5.1",
"nan": "^2.13.2",
@@ -13718,71 +12246,15 @@
}
},
"object.fromentries": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.2.tgz",
"integrity": "sha512-r3ZiBH7MQppDJVLx6fhD618GKNG40CZYH9wgwdhKxBDDbQgjeWGGd4AtkZad84d291YxvWe7bJGuE65Anh0dxQ==",
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.1.tgz",
"integrity": "sha512-PUQv8Hbg3j2QX0IQYv3iAGCbGcu4yY4KQ92/dhA4sFSixBmSmp13UpDLs6jGK8rBtbmhNNIK99LD2k293jpiGA==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"es-abstract": "^1.17.0-next.1",
"es-abstract": "^1.15.0",
"function-bind": "^1.1.1",
"has": "^1.0.3"
},
"dependencies": {
"es-abstract": {
"version": "1.17.4",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz",
"integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==",
"dev": true,
"requires": {
"es-to-primitive": "^1.2.1",
"function-bind": "^1.1.1",
"has": "^1.0.3",
"has-symbols": "^1.0.1",
"is-callable": "^1.1.5",
"is-regex": "^1.0.5",
"object-inspect": "^1.7.0",
"object-keys": "^1.1.1",
"object.assign": "^4.1.0",
"string.prototype.trimleft": "^2.1.1",
"string.prototype.trimright": "^2.1.1"
}
},
"is-callable": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz",
"integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==",
"dev": true
},
"is-regex": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
"integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
"dev": true,
"requires": {
"has": "^1.0.3"
}
},
"string.prototype.trimleft": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz",
"integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"function-bind": "^1.1.1"
}
},
"string.prototype.trimright": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz",
"integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"function-bind": "^1.1.1"
}
}
}
},
"object.getownpropertydescriptors": {
@@ -13805,71 +12277,15 @@
}
},
"object.values": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz",
"integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==",
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.0.tgz",
"integrity": "sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"es-abstract": "^1.17.0-next.1",
"es-abstract": "^1.12.0",
"function-bind": "^1.1.1",
"has": "^1.0.3"
},
"dependencies": {
"es-abstract": {
"version": "1.17.4",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz",
"integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==",
"dev": true,
"requires": {
"es-to-primitive": "^1.2.1",
"function-bind": "^1.1.1",
"has": "^1.0.3",
"has-symbols": "^1.0.1",
"is-callable": "^1.1.5",
"is-regex": "^1.0.5",
"object-inspect": "^1.7.0",
"object-keys": "^1.1.1",
"object.assign": "^4.1.0",
"string.prototype.trimleft": "^2.1.1",
"string.prototype.trimright": "^2.1.1"
}
},
"is-callable": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz",
"integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==",
"dev": true
},
"is-regex": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
"integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
"dev": true,
"requires": {
"has": "^1.0.3"
}
},
"string.prototype.trimleft": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz",
"integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"function-bind": "^1.1.1"
}
},
"string.prototype.trimright": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz",
"integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"function-bind": "^1.1.1"
}
}
}
},
"obuf": {
@@ -13902,12 +12318,12 @@
}
},
"onetime": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz",
"integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==",
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
"integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
"dev": true,
"requires": {
"mimic-fn": "^2.1.0"
"mimic-fn": "^1.0.0"
}
},
"open": {
@@ -14159,9 +12575,9 @@
"dev": true
},
"pako": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz",
"integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==",
"dev": true
},
"parallel-transform": {
@@ -14182,9 +12598,9 @@
"dev": true
},
"readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
"core-util-is": "~1.0.0",
@@ -14475,6 +12891,12 @@
"semver-compare": "^1.0.0"
}
},
"pluralize": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz",
"integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==",
"dev": true
},
"pn": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz",
@@ -15495,15 +13917,6 @@
"node-releases": "^1.1.25"
}
},
"cli-cursor": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
"integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
"dev": true,
"requires": {
"restore-cursor": "^2.0.0"
}
},
"dir-glob": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz",
@@ -15514,15 +13927,6 @@
"path-type": "^3.0.0"
}
},
"figures": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
"integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
"dev": true,
"requires": {
"escape-string-regexp": "^1.0.5"
}
},
"globby": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/globby/-/globby-8.0.2.tgz",
@@ -15559,37 +13963,6 @@
"through": "^2.3.6"
}
},
"mimic-fn": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
"integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
"dev": true
},
"mute-stream": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
"integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
"dev": true
},
"onetime": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
"integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
"dev": true,
"requires": {
"mimic-fn": "^1.0.0"
}
},
"restore-cursor": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
"integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
"dev": true,
"requires": {
"onetime": "^2.0.0",
"signal-exit": "^3.0.2"
}
},
"slash": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
@@ -15610,9 +13983,9 @@
}
},
"react-error-overlay": {
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.5.tgz",
"integrity": "sha512-+DMR2k5c6BqMDSMF8hLH0vYKtKTeikiFW+fj0LClN+XZg4N9b8QUAdHC62CGWNLTi/gnuuemNcNcTFrCvK1f+A==",
"version": "6.0.4",
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.4.tgz",
"integrity": "sha512-ueZzLmHltszTshDMwyfELDq8zOA803wQ1ZuzCccXa1m57k1PxSHfflPD5W9YIiTXLs0JTLzoj6o1LuM5N6zzNA==",
"dev": true
},
"react-intl": {
@@ -15758,9 +14131,9 @@
"dev": true
},
"readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
"core-util-is": "~1.0.0",
@@ -15818,33 +14191,14 @@
}
},
"redux": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/redux/-/redux-4.0.5.tgz",
"integrity": "sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w==",
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/redux/-/redux-4.0.4.tgz",
"integrity": "sha512-vKv4WdiJxOWKxK0yRoaK3Y4pxxB0ilzVx6dszU2W8wLxlb2yikRph4iV/ymtdJ6ZxpBLFbyrxklnT5yBbQSl3Q==",
"requires": {
"loose-envify": "^1.4.0",
"symbol-observable": "^1.2.0"
}
},
"redux-devtools-extension": {
"version": "2.13.8",
"resolved": "https://registry.npmjs.org/redux-devtools-extension/-/redux-devtools-extension-2.13.8.tgz",
"integrity": "sha512-8qlpooP2QqPtZHQZRhx3x3OP5skEV1py/zUdMY28WNAocbafxdG2tRD1MWE7sp8obGMNYuLWanhhQ7EQvT1FBg=="
},
"redux-immutable-state-invariant": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/redux-immutable-state-invariant/-/redux-immutable-state-invariant-2.1.0.tgz",
"integrity": "sha512-3czbDKs35FwiBRsx/3KabUk5zSOoTXC+cgVofGkpBNv3jQcqIe5JrHcF5AmVt7B/4hyJ8MijBIpCJ8cife6yJg==",
"requires": {
"invariant": "^2.1.0",
"json-stringify-safe": "^5.0.1"
}
},
"redux-thunk": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz",
"integrity": "sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw=="
},
"reflect.ownkeys": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz",
@@ -15896,69 +14250,12 @@
"dev": true
},
"regexp.prototype.flags": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz",
"integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==",
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.2.0.tgz",
"integrity": "sha512-ztaw4M1VqgMwl9HlPpOuiYgItcHlunW0He2fE6eNfT6E/CF2FtYi9ofOYe4mKntstYk0Fyh/rDRBdS3AnxjlrA==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"es-abstract": "^1.17.0-next.1"
},
"dependencies": {
"es-abstract": {
"version": "1.17.4",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz",
"integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==",
"dev": true,
"requires": {
"es-to-primitive": "^1.2.1",
"function-bind": "^1.1.1",
"has": "^1.0.3",
"has-symbols": "^1.0.1",
"is-callable": "^1.1.5",
"is-regex": "^1.0.5",
"object-inspect": "^1.7.0",
"object-keys": "^1.1.1",
"object.assign": "^4.1.0",
"string.prototype.trimleft": "^2.1.1",
"string.prototype.trimright": "^2.1.1"
}
},
"is-callable": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz",
"integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==",
"dev": true
},
"is-regex": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
"integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
"dev": true,
"requires": {
"has": "^1.0.3"
}
},
"string.prototype.trimleft": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz",
"integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"function-bind": "^1.1.1"
}
},
"string.prototype.trimright": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz",
"integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"function-bind": "^1.1.1"
}
}
"define-properties": "^1.1.2"
}
},
"regexpp": {
@@ -15988,9 +14285,9 @@
"dev": true
},
"regjsparser": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.2.tgz",
"integrity": "sha512-E9ghzUtoLwDekPT0DYCp+c4h+bvuUpe6rRHCTYn6eGoqj1LgKXxT6I0Il4WbjhQkOghzi/V+y03bPKvbllL93Q==",
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.0.tgz",
"integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==",
"dev": true,
"requires": {
"jsesc": "~0.5.0"
@@ -16179,17 +14476,45 @@
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
"dev": true
},
"require-uncached": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
"integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=",
"dev": true,
"requires": {
"caller-path": "^0.1.0",
"resolve-from": "^1.0.0"
},
"dependencies": {
"caller-path": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz",
"integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=",
"dev": true,
"requires": {
"callsites": "^0.2.0"
}
},
"callsites": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz",
"integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=",
"dev": true
},
"resolve-from": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz",
"integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=",
"dev": true
}
}
},
"requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
"dev": true
},
"reselect": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/reselect/-/reselect-4.0.0.tgz",
"integrity": "sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA=="
},
"resolve": {
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.13.1.tgz",
@@ -16332,12 +14657,12 @@
}
},
"restore-cursor": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
"integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
"integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
"dev": true,
"requires": {
"onetime": "^5.1.0",
"onetime": "^2.0.0",
"signal-exit": "^3.0.2"
}
},
@@ -16476,10 +14801,25 @@
"integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=",
"dev": true
},
"rx-lite": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz",
"integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=",
"dev": true
},
"rx-lite-aggregates": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz",
"integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=",
"dev": true,
"requires": {
"rx-lite": "*"
}
},
"rxjs": {
"version": "6.5.4",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz",
"integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==",
"version": "6.5.3",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz",
"integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==",
"dev": true,
"requires": {
"tslib": "^1.9.0"
@@ -17728,9 +16068,9 @@
"dev": true
},
"readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
"core-util-is": "~1.0.0",
@@ -17782,9 +16122,9 @@
"dev": true
},
"readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
"core-util-is": "~1.0.0",
@@ -17843,9 +16183,9 @@
"dev": true
},
"readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
"core-util-is": "~1.0.0",
@@ -18026,9 +16366,9 @@
},
"dependencies": {
"schema-utils": {
"version": "2.6.4",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.4.tgz",
"integrity": "sha512-VNjcaUxVnEeun6B2fiiUDjXXBtD4ZSH7pdbfIu1pOFwgptDPLMo/z9jr4sUfsjFVPqDCEin/F7IYlq7/E6yDbQ==",
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.1.tgz",
"integrity": "sha512-0WXHDs1VDJyo+Zqs9TKLKyD/h7yDpHUhEFsM2CzkICFdoX1av+GBq/J2xRTFfsQO5kBfhZzANf2VcIm84jqDbg==",
"dev": true,
"requires": {
"ajv": "^6.10.2",
@@ -18086,9 +16426,9 @@
"dev": true
},
"readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
"core-util-is": "~1.0.0",
@@ -18126,9 +16466,9 @@
}
},
"svg-parser": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.3.tgz",
"integrity": "sha512-fnCWiifNhK8i2Z7b9R5tbNahpxrRdAaQbnoxKlT2KrSCj9Kq/yBSgulCRgBJRhy1dPnSY5slg5ehPUnzpEcHlg==",
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.2.tgz",
"integrity": "sha512-1gtApepKFweigFZj3sGO8KT8LvVZK8io146EzXrpVuWCDAbISz/yMucco3hWTkpZNoPabM+dnMOpy6Swue68Zg==",
"dev": true
},
"svgo": {
@@ -18433,9 +16773,9 @@
"dev": true
},
"readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
"core-util-is": "~1.0.0",
@@ -18492,9 +16832,9 @@
}
},
"terser": {
"version": "4.6.3",
"resolved": "https://registry.npmjs.org/terser/-/terser-4.6.3.tgz",
"integrity": "sha512-Lw+ieAXmY69d09IIc/yqeBqXpEQIpDGZqT34ui1QWXIUpR2RjbqEkT8X7Lgex19hslSqcWM5iMN2kM11eMsESQ==",
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/terser/-/terser-4.4.2.tgz",
"integrity": "sha512-Uufrsvhj9O1ikwgITGsZ5EZS6qPokUOkCegS7fYOdGTv+OA90vndUbU6PEjr5ePqHfNUbGyMO7xyIZv2MhsALQ==",
"dev": true,
"requires": {
"commander": "^2.20.0",
@@ -18566,9 +16906,9 @@
"dev": true
},
"readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
"core-util-is": "~1.0.0",
@@ -18939,9 +17279,9 @@
}
},
"universal-cookie": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/universal-cookie/-/universal-cookie-4.0.3.tgz",
"integrity": "sha512-YbEHRs7bYOBTIWedTR9koVEe2mXrq+xdjTJZcoKJK/pQaE6ni28ak2AKXFpevb+X6w3iU5SXzWDiJkmpDRb9qw==",
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/universal-cookie/-/universal-cookie-4.0.2.tgz",
"integrity": "sha512-n14lhA//lQeYRweP9j9uXsshN9Cs4LunVSnvAGmnA69SofwsjpUU03geaCaPC9LlsH2rkBy99o3zxQyVOldGvA==",
"requires": {
"@types/cookie": "^0.3.3",
"@types/object-assign": "^4.0.30",
@@ -19076,9 +17416,9 @@
"dev": true
},
"schema-utils": {
"version": "2.6.4",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.4.tgz",
"integrity": "sha512-VNjcaUxVnEeun6B2fiiUDjXXBtD4ZSH7pdbfIu1pOFwgptDPLMo/z9jr4sUfsjFVPqDCEin/F7IYlq7/E6yDbQ==",
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.1.tgz",
"integrity": "sha512-0WXHDs1VDJyo+Zqs9TKLKyD/h7yDpHUhEFsM2CzkICFdoX1av+GBq/J2xRTFfsQO5kBfhZzANf2VcIm84jqDbg==",
"dev": true,
"requires": {
"ajv": "^6.10.2",
@@ -19202,9 +17542,9 @@
"dev": true
},
"vendors": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz",
"integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.3.tgz",
"integrity": "sha512-fOi47nsJP5Wqefa43kyWSg80qF+Q3XA6MUkgi7Hp1HQaKDQW4cQrK2D0P7mmbFtsV1N89am55Yru/nyEwRubcw==",
"dev": true
},
"verror": {

View File

@@ -14,7 +14,7 @@
"build": "fedx-scripts webpack",
"i18n_extract": "BABEL_ENV=i18n fedx-scripts babel src --quiet > /dev/null",
"is-es5": "es-check es5 ./dist/*.js",
"lint": "fedx-scripts eslint --ext .js --ext .jsx .",
"lint": "fedx-scripts eslint",
"snapshot": "fedx-scripts jest --updateSnapshot",
"start": "fedx-scripts webpack-dev-server --progress",
"test": "fedx-scripts jest --coverage --passWithNoTests"
@@ -36,15 +36,13 @@
"dependencies": {
"@edx/frontend-component-footer": "^10.0.6",
"@edx/frontend-component-header": "^2.0.3",
"@edx/frontend-platform": "^1.3.1",
"@edx/frontend-platform": "^1.1.11",
"@edx/paragon": "^7.2.0",
"@fortawesome/fontawesome-svg-core": "^1.2.26",
"@fortawesome/free-brands-svg-icons": "^5.12.0",
"@fortawesome/free-regular-svg-icons": "^5.12.0",
"@fortawesome/free-solid-svg-icons": "^5.12.0",
"@fortawesome/react-fontawesome": "^0.1.8",
"@reduxjs/toolkit": "^1.2.3",
"classnames": "^2.2.6",
"core-js": "^3.6.2",
"prop-types": "^15.7.2",
"react": "^16.12.0",
@@ -52,12 +50,11 @@
"react-redux": "^7.1.3",
"react-router": "^5.1.2",
"react-router-dom": "^5.1.2",
"react-transition-group": "^4.3.0",
"redux": "^4.0.5",
"redux": "^4.0.4",
"regenerator-runtime": "^0.13.3"
},
"devDependencies": {
"@edx/frontend-build": "^3.0.0",
"@edx/frontend-build": "^2.0.5",
"codecov": "^3.6.1",
"es-check": "^5.1.0",
"glob": "^7.1.6",

View File

@@ -0,0 +1,74 @@
import React from 'react';
import PropTypes from 'prop-types';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import messages from './messages';
import NavTab from './NavTab';
function CourseTabsNavigation({ activeTabSlug, courseTabs, intl }) {
const courseNavTabs = courseTabs.map(({ slug, ...courseTab }) => (
<NavTab
isActive={slug === activeTabSlug}
key={slug}
{...courseTab}
/>
));
return (
<nav
aria-label={intl.formatMessage(messages['learn.navigation.course.tabs.label'])}
className="nav nav-underline-tabs"
>
{courseNavTabs}
</nav>
);
}
CourseTabsNavigation.propTypes = {
activeTabSlug: PropTypes.string,
courseTabs: PropTypes.arrayOf(PropTypes.shape({
title: PropTypes.string.isRequired,
priority: PropTypes.number.isRequired,
slug: PropTypes.string.isRequired,
url: PropTypes.string.isRequired,
})),
intl: intlShape.isRequired,
};
CourseTabsNavigation.defaultProps = {
activeTabSlug: undefined,
courseTabs: [
{
title: 'Course',
slug: 'course',
priority: 1,
url: 'http://localhost:18000/courses/course-v1:edX+DemoX+Demo_Course/course/',
},
{
title: 'Discussion',
slug: 'discussion',
priority: 2,
url: 'http://localhost:18000/courses/course-v1:edX+DemoX+Demo_Course/discussion/forum/',
},
{
title: 'Wiki',
slug: 'wiki',
priority: 3,
url: 'http://localhost:18000/courses/course-v1:edX+DemoX+Demo_Course/course_wiki',
},
{
title: 'Progress',
slug: 'progress',
priority: 4,
url: 'http://localhost:18000/courses/course-v1:edX+DemoX+Demo_Course/progress',
},
{
title: 'Instructor',
slug: 'instructor',
priority: 5,
url: 'http://localhost:18000/courses/course-v1:edX+DemoX+Demo_Course/instructor',
},
],
};
export default injectIntl(CourseTabsNavigation);

View File

@@ -1,7 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { getConfig } from '@edx/frontend-platform';
export default function NavTab(props) {
@@ -15,9 +14,7 @@ export default function NavTab(props) {
attrs.className,
);
// TODO: We probably don't want to blindly add LMS_BASE_URL here. I think it's more likely
// that the course metadata API should provide us fully qualified URLs.
return <a {...attrs} className={className} href={`${getConfig().LMS_BASE_URL}${url}`}>{title}</a>;
return <a {...attrs} className={className} href={url}>{title}</a>;
}
NavTab.propTypes = {

View File

@@ -1,110 +0,0 @@
import React, { useEffect } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { history, getConfig } from '@edx/frontend-platform';
import { fetchCourseMetadata, courseMetadataShape } from '../data/course-meta';
import { fetchCourseBlocks } from '../data/course-blocks';
import messages from './messages';
import PageLoading from '../PageLoading';
import Course from './course/Course';
function CourseContainer(props) {
const {
intl,
match,
courseId,
blocks: models,
metadata,
} = props;
const {
courseUsageKey,
sequenceId,
unitId,
} = match.params;
useEffect(() => {
props.fetchCourseMetadata(courseUsageKey);
props.fetchCourseBlocks(courseUsageKey);
}, [courseUsageKey]);
useEffect(() => {
if (courseId && !sequenceId) {
// TODO: This is temporary until we get an actual activeSequenceId into the course model data.
const course = models[courseId];
const chapter = models[course.children[0]];
const activeSequenceId = chapter.children[0];
history.push(`/course/${courseUsageKey}/${activeSequenceId}`);
}
}, [courseUsageKey, courseId, sequenceId]);
const metadataLoaded = metadata.fetchState === 'loaded';
useEffect(() => {
if (metadataLoaded && !metadata.userHasAccess) {
global.location.assign(`${getConfig().LMS_BASE_URL}/courses/${courseUsageKey}/course/`);
}
}, [metadataLoaded]);
// Whether or not the container is ready to render the Course.
const ready = metadataLoaded && courseId && sequenceId;
return (
<main className="flex-grow-1 d-flex flex-column">
{ready ? (
<Course
courseOrg={props.metadata.org}
courseNumber={props.metadata.number}
courseName={props.metadata.name}
courseUsageKey={courseUsageKey}
courseId={courseId}
isEnrolled={props.metadata.isEnrolled}
sequenceId={sequenceId}
unitId={unitId}
models={models}
tabs={props.metadata.tabs}
verifiedMode={props.metadata.verifiedMode}
/>
) : (
<PageLoading
srMessage={intl.formatMessage(messages['learn.loading.learning.sequence'])}
/>
)}
</main>
);
}
CourseContainer.propTypes = {
intl: intlShape.isRequired,
courseId: PropTypes.string,
blocks: PropTypes.objectOf(PropTypes.shape({
id: PropTypes.string,
})),
metadata: courseMetadataShape,
fetchCourseMetadata: PropTypes.func.isRequired,
fetchCourseBlocks: PropTypes.func.isRequired,
match: PropTypes.shape({
params: PropTypes.shape({
courseUsageKey: PropTypes.string.isRequired,
sequenceId: PropTypes.string,
unitId: PropTypes.string,
}).isRequired,
}).isRequired,
};
CourseContainer.defaultProps = {
blocks: {},
metadata: undefined,
courseId: undefined,
};
const mapStateToProps = state => ({
courseId: state.courseBlocks.root,
metadata: state.courseMeta,
blocks: state.courseBlocks.blocks,
});
export default connect(mapStateToProps, {
fetchCourseMetadata,
fetchCourseBlocks,
})(injectIntl(CourseContainer));

View File

@@ -1,46 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
function InstructorToolbar(props) {
// TODO: Only render this toolbar if the user is course staff
if (!props.activeUnitLmsWebUrl) {
return null;
}
return (
<div className="bg-primary text-light">
<div className="container-fluid py-3 d-flex justify-content-end align-items-center">
<div>
<p className="mb-0 mr-5">
You are currently previewing the new learning sequence experience. This preview is to allow for early content testing, especially for custom content blocks, with the goal of ensuring it renders as expected in the next experience. You can learn more through the following <a className="text-white" style={{ textDecoration: 'underline' }} href="https://partners.edx.org/announcements/author-preview-learning-sequence-experience-update" target="blank" rel="noopener">Partner Portal post</a>. Please report any issues or provide <a className="text-white" style={{ textDecoration: 'underline' }} target="blank" rel="noopener" href="https://forms.gle/R6jMYJNTCj1vgC1D6">feedback using the linked form</a>.
</p>
</div>
<div className="flex-shrink-0">
<a className="btn d-block btn-outline-light" href={props.activeUnitLmsWebUrl}>View unit in the existing experience</a>
</div>
</div>
</div>
);
}
InstructorToolbar.propTypes = {
activeUnitLmsWebUrl: PropTypes.string,
};
InstructorToolbar.defaultProps = {
activeUnitLmsWebUrl: undefined,
};
const mapStateToProps = (state, props) => {
if (!props.unitId) {
return {};
}
const activeUnit = state.courseBlocks.blocks[props.unitId];
return {
activeUnitLmsWebUrl: activeUnit.lmsWebUrl,
};
};
export default connect(mapStateToProps)(InstructorToolbar);

View File

@@ -1,138 +0,0 @@
import React, { useCallback } from 'react';
import PropTypes from 'prop-types';
import { history } from '@edx/frontend-platform';
import CourseBreadcrumbs from './CourseBreadcrumbs';
import SequenceContainer from './SequenceContainer';
import { createSequenceIdList } from '../utils';
import AlertList from '../../user-messages/AlertList';
import CourseHeader from './CourseHeader';
import CourseSock from './course-sock';
import CourseTabsNavigation from './CourseTabsNavigation';
import InstructorToolbar from '../InstructorToolbar';
import { useLogistrationAlert, useEnrollmentAlert } from '../../hooks';
const EnrollmentAlert = React.lazy(() => import('../../enrollment-alert'));
const LogistrationAlert = React.lazy(() => import('../../logistration-alert'));
export default function Course({
courseId,
courseNumber,
courseName,
courseOrg,
courseUsageKey,
isEnrolled,
models,
sequenceId,
tabs,
unitId,
verifiedMode,
}) {
const nextSequenceHandler = useCallback(() => {
const sequenceIds = createSequenceIdList(models, courseId);
const currentIndex = sequenceIds.indexOf(sequenceId);
if (currentIndex < sequenceIds.length - 1) {
const nextSequenceId = sequenceIds[currentIndex + 1];
const nextSequence = models[nextSequenceId];
const nextUnitId = nextSequence.children[0];
history.push(`/course/${courseUsageKey}/${nextSequenceId}/${nextUnitId}`);
}
});
const previousSequenceHandler = useCallback(() => {
const sequenceIds = createSequenceIdList(models, courseId);
const currentIndex = sequenceIds.indexOf(sequenceId);
if (currentIndex > 0) {
const previousSequenceId = sequenceIds[currentIndex - 1];
const previousSequence = models[previousSequenceId];
const previousUnitId = previousSequence.children[previousSequence.children.length - 1];
history.push(`/course/${courseUsageKey}/${previousSequenceId}/${previousUnitId}`);
}
});
useLogistrationAlert();
useEnrollmentAlert(isEnrolled);
return (
<>
<CourseHeader
courseOrg={courseOrg}
courseNumber={courseNumber}
courseName={courseName}
/>
<InstructorToolbar
courseUsageKey={courseUsageKey}
courseId={courseId}
sequenceId={sequenceId}
unitId={unitId}
/>
<CourseTabsNavigation tabs={tabs} activeTabSlug="courseware" />
<div className="container-fluid flex-grow-1 d-flex flex-column">
<AlertList
className="my-3"
topic="course"
customAlerts={{
clientEnrollmentAlert: EnrollmentAlert,
clientLogistrationAlert: LogistrationAlert,
}}
/>
<CourseBreadcrumbs
courseUsageKey={courseUsageKey}
courseId={courseId}
sequenceId={sequenceId}
unitId={unitId}
models={models}
/>
<SequenceContainer
key={sequenceId}
courseUsageKey={courseUsageKey}
courseId={courseId}
sequenceId={sequenceId}
unitId={unitId}
models={models}
onNext={nextSequenceHandler}
onPrevious={previousSequenceHandler}
/>
</div>
{verifiedMode && <CourseSock verifiedMode={verifiedMode} />}
</>
);
}
Course.propTypes = {
courseOrg: PropTypes.string.isRequired,
courseNumber: PropTypes.string.isRequired,
courseName: PropTypes.string.isRequired,
courseUsageKey: PropTypes.string.isRequired,
courseId: PropTypes.string.isRequired,
sequenceId: PropTypes.string.isRequired,
unitId: PropTypes.string,
isEnrolled: PropTypes.bool,
models: PropTypes.objectOf(PropTypes.shape({
id: PropTypes.string.isRequired,
displayName: PropTypes.string.isRequired,
children: PropTypes.arrayOf(PropTypes.string),
parentId: PropTypes.string,
})).isRequired,
tabs: PropTypes.arrayOf(PropTypes.shape({
slug: PropTypes.string.isRequired,
priority: PropTypes.number.isRequired,
title: PropTypes.string.isRequired,
type: PropTypes.string.isRequired,
url: PropTypes.string.isRequired,
})).isRequired,
verifiedMode: PropTypes.shape({
price: PropTypes.number.isRequired,
currency: PropTypes.string.isRequired,
currencySymbol: PropTypes.string,
sku: PropTypes.string.isRequired,
upgradeUrl: PropTypes.string.isRequired,
}),
};
Course.defaultProps = {
unitId: undefined,
isEnrolled: false,
verifiedMode: null,
};

View File

@@ -1,20 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
export default function CourseBreadcrumb({ url, label }) {
return (
<React.Fragment key={`${label}-${url}`}>
<li className="list-inline-item text-gray-300" role="presentation" aria-label="spacer">
/
</li>
<li className="list-inline-item">
<a href={url}>{label}</a>
</li>
</React.Fragment>
);
}
CourseBreadcrumb.propTypes = {
url: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
};

View File

@@ -1,56 +0,0 @@
import React, { useMemo } from 'react';
import PropTypes from 'prop-types';
import { getConfig } from '@edx/frontend-platform';
import { FormattedMessage } from '@edx/frontend-platform/i18n';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faHome } from '@fortawesome/free-solid-svg-icons';
import CourseBreadcrumb from './CourseBreadcrumb';
export default function CourseBreadcrumbs({
courseUsageKey, courseId, sequenceId, models,
}) {
const links = useMemo(() => {
const sectionId = models[sequenceId].parentId;
return [sectionId, sequenceId].map((nodeId) => {
const node = models[nodeId];
return {
id: node.id,
label: node.displayName,
url: `${getConfig().LMS_BASE_URL}/courses/${courseUsageKey}/course/#${node.id}`,
};
});
}, [courseUsageKey, courseId, sequenceId, models]);
return (
<nav aria-label="breadcrumb" className="my-4">
<ol className="list-inline m-0">
<li className="list-inline-item">
<a href={`${getConfig().LMS_BASE_URL}/courses/${courseUsageKey}/course/`}>
<FontAwesomeIcon icon={faHome} className="mr-2" />
<FormattedMessage
id="learn.breadcrumb.navigation.course.home"
description="The course home link in breadcrumbs nav"
defaultMessage="Course"
/>
</a>
</li>
{links.map(({ id, url, label }, i) => (
<CourseBreadcrumb key={id} url={url} label={label} last={i === links.length - 1} />
))}
</ol>
</nav>
);
}
CourseBreadcrumbs.propTypes = {
courseUsageKey: PropTypes.string.isRequired,
courseId: PropTypes.string.isRequired,
sequenceId: PropTypes.string.isRequired,
models: PropTypes.objectOf(PropTypes.shape({
id: PropTypes.string.isRequired,
displayName: PropTypes.string.isRequired,
children: PropTypes.arrayOf(PropTypes.string),
parentId: PropTypes.string,
})).isRequired,
};

View File

@@ -1,68 +0,0 @@
import React, { useContext } from 'react';
import PropTypes from 'prop-types';
import { Dropdown } from '@edx/paragon';
import { getConfig } from '@edx/frontend-platform';
import { AppContext } from '@edx/frontend-platform/react';
import logo from './logo.svg';
function LinkedLogo({
href,
src,
alt,
...attributes
}) {
return (
<a href={href} {...attributes}>
<img className="d-block" src={src} alt={alt} />
</a>
);
}
LinkedLogo.propTypes = {
href: PropTypes.string.isRequired,
src: PropTypes.string.isRequired,
alt: PropTypes.string.isRequired,
};
export default function CourseHeader({
courseOrg, courseNumber, courseName,
}) {
const { authenticatedUser } = useContext(AppContext);
return (
<header>
<div className="container-fluid py-2 d-flex align-items-center ">
<LinkedLogo
className="logo"
href={`${getConfig().LMS_BASE_URL}/dashboard`}
src={logo}
alt={getConfig().SITE_NAME}
/>
<div className="flex-grow-1" style={{ lineHeight: 1 }}>
<span className="d-block small m-0">{courseOrg} {courseNumber}</span>
<span className="d-block m-0 font-weight-bold">{courseName}</span>
</div>
<Dropdown>
<Dropdown.Button>
{authenticatedUser.username}
</Dropdown.Button>
<Dropdown.Menu className="dropdown-menu-right">
<Dropdown.Item href={`${getConfig().LMS_BASE_URL}/dashboard`}>Dashboard</Dropdown.Item>
<Dropdown.Item href={`${getConfig().LMS_BASE_URL}/u/${authenticatedUser.username}`}>Profile</Dropdown.Item>
<Dropdown.Item href={`${getConfig().LMS_BASE_URL}/account/settings`}>Account</Dropdown.Item>
<Dropdown.Item href={getConfig().ORDER_HISTORY_URL}>Order History</Dropdown.Item>
<Dropdown.Item href={getConfig().LOGOUT_URL}>Sign Out</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
</div>
</header>
);
}
CourseHeader.propTypes = {
courseOrg: PropTypes.string.isRequired,
courseNumber: PropTypes.string.isRequired,
courseName: PropTypes.string.isRequired,
};

View File

@@ -1,51 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import classNames from 'classnames';
import messages from './messages';
import NavTab from './NavTab';
function CourseTabsNavigation({
activeTabSlug, tabs, intl, className,
}) {
const courseNavTabs = tabs.map(({ slug, ...courseTab }) => (
<NavTab
isActive={slug === activeTabSlug}
key={slug}
{...courseTab}
/>
));
return (
<div className="course-tabs-navigation">
<div className="container-fluid">
<nav
aria-label={intl.formatMessage(messages['learn.navigation.course.tabs.label'])}
className={classNames('nav nav-underline-tabs', className)}
>
{courseNavTabs}
</nav>
</div>
</div>
);
}
CourseTabsNavigation.propTypes = {
activeTabSlug: PropTypes.string,
className: PropTypes.string,
tabs: PropTypes.arrayOf(PropTypes.shape({
title: PropTypes.string.isRequired,
priority: PropTypes.number.isRequired,
slug: PropTypes.string.isRequired,
url: PropTypes.string.isRequired,
})).isRequired,
intl: intlShape.isRequired,
};
CourseTabsNavigation.defaultProps = {
activeTabSlug: undefined,
className: null,
};
export default injectIntl(CourseTabsNavigation);

View File

@@ -1,246 +0,0 @@
import React, {
useState, useCallback, useRef, useEffect,
} from 'react';
import { CSSTransition } from 'react-transition-group';
import PropTypes from 'prop-types';
export function MenuTrigger({ tag, className, ...attributes }) {
return React.createElement(tag, {
className: `menu-trigger ${className}`,
...attributes,
});
}
MenuTrigger.propTypes = {
tag: PropTypes.string,
className: PropTypes.string,
};
MenuTrigger.defaultProps = {
tag: 'div',
className: null,
};
const MenuTriggerType = (<MenuTrigger />).type;
export function MenuContent({ tag, className, ...attributes }) {
return React.createElement(tag, {
className: ['menu-content', className].join(' '),
...attributes,
});
}
MenuContent.propTypes = {
tag: PropTypes.string,
className: PropTypes.string,
};
MenuContent.defaultProps = {
tag: 'div',
className: null,
};
export function Menu({
className,
children,
tag,
transitionTimeout,
transitionClassName,
respondToPointerEvents,
onOpen,
onClose,
closeOnDocumentClick,
...attributes
}) {
const [expanded, setExpanded] = useState(false);
const menu = useRef(null);
const open = useCallback(() => {
if (onOpen) {
onOpen();
}
setExpanded(true);
}, [onOpen]);
const close = useCallback(() => {
if (onClose) {
onClose();
}
setExpanded(false);
}, [onClose]);
const toggle = useCallback(() => {
if (expanded) {
close();
} else {
open();
}
}, [expanded]);
const onDocumentClick = useCallback((e) => {
if (!closeOnDocumentClick) {
return;
}
const clickIsInMenu = menu.current === e.target || menu.current.contains(e.target);
if (clickIsInMenu) {
return;
}
close();
}, [closeOnDocumentClick]);
useEffect(() => {
if (expanded) {
// Listen to touchend and click events to ensure the menu
// can be closed on mobile, pointer, and mixed input devices
document.addEventListener('touchend', onDocumentClick, true);
document.addEventListener('click', onDocumentClick, true);
} else {
document.removeEventListener('touchend', onDocumentClick, true);
document.removeEventListener('click', onDocumentClick, true);
}
return () => {
document.removeEventListener('touchend', onDocumentClick, true);
document.removeEventListener('click', onDocumentClick, true);
};
}, [expanded]);
const onTriggerClick = useCallback((e) => {
// Let the browser follow the link of the trigger if the menu
// is already expanded and the trigger has an href attribute
if (expanded && e.target.getAttribute('href')) {
return;
}
e.preventDefault();
toggle();
}, []);
const onMouseEnter = useCallback(() => {
if (!respondToPointerEvents) { return; }
open();
}, [respondToPointerEvents]);
const onMouseLeave = useCallback(() => {
if (!respondToPointerEvents) { return; }
close();
}, [respondToPointerEvents]);
const getFocusableElements = useCallback(() => menu.current.querySelectorAll('button:not([disabled]), [href]:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"]):not([disabled])'), []);
const focusNext = useCallback(() => {
const focusableElements = Array.from(getFocusableElements());
const activeIndex = focusableElements.indexOf(document.activeElement);
const nextIndex = (activeIndex + 1) % focusableElements.length;
focusableElements[nextIndex].focus();
}, []);
const focusPrevious = useCallback(() => {
const focusableElements = Array.from(getFocusableElements());
const activeIndex = focusableElements.indexOf(document.activeElement);
const previousIndex = (activeIndex || focusableElements.length) - 1;
focusableElements[previousIndex].focus();
}, []);
const onKeyDown = useCallback((e) => {
if (!expanded) {
return;
}
switch (e.key) {
case 'Escape': {
e.preventDefault();
e.stopPropagation();
getFocusableElements()[0].focus();
close();
break;
}
case 'Enter': {
// Using focusable elements instead of a ref to the trigger
// because Hyperlink and Button can handle refs as functional components
if (document.activeElement === getFocusableElements()[0]) {
e.preventDefault();
toggle();
}
break;
}
case 'Tab': {
e.preventDefault();
if (e.shiftKey) {
focusPrevious();
} else {
focusNext();
}
break;
}
case 'ArrowDown': {
e.preventDefault();
focusNext();
break;
}
case 'ArrowUp': {
e.preventDefault();
focusPrevious();
break;
}
default:
}
}, [expanded]);
useEffect(() => () => {
// Call onClose callback when unmounting and open
if (expanded && onClose) {
onClose();
}
}, []);
const wrappedChildren = React.Children.map(children, (child) => {
if (child.type === MenuTriggerType) {
return React.cloneElement(child, {
onClick: onTriggerClick,
'aria-haspopup': 'menu',
'aria-expanded': expanded,
});
}
return (
<CSSTransition
in={expanded}
timeout={transitionTimeout}
classNames={transitionClassName}
unmountOnExit
>
{child}
</CSSTransition>
);
});
const rootClassName = expanded ? 'menu expanded' : 'menu';
return React.createElement(tag, {
className: `${rootClassName} ${className}`,
ref: menu,
onKeyDown,
onMouseEnter,
onMouseLeave,
...attributes,
}, wrappedChildren);
}
Menu.propTypes = {
tag: PropTypes.string,
onClose: PropTypes.func,
onOpen: PropTypes.func,
closeOnDocumentClick: PropTypes.bool,
respondToPointerEvents: PropTypes.bool,
className: PropTypes.string,
transitionTimeout: PropTypes.number,
transitionClassName: PropTypes.string,
children: PropTypes.arrayOf(PropTypes.node).isRequired,
};
Menu.defaultProps = {
tag: 'div',
className: null,
onClose: null,
onOpen: null,
respondToPointerEvents: false,
closeOnDocumentClick: true,
transitionTimeout: 250,
transitionClassName: 'menu-content',
};

View File

@@ -1,160 +0,0 @@
/* eslint-disable no-plusplus */
import React, { useEffect, useCallback, useMemo } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { history } from '@edx/frontend-platform';
import messages from '../messages';
import PageLoading from '../../PageLoading';
import Sequence from '../sequence/Sequence';
import AlertList from '../../user-messages/AlertList';
import { fetchSequenceMetadata, checkBlockCompletion, saveSequencePosition } from '../../data/course-blocks';
function SequenceContainer(props) {
const {
courseUsageKey,
courseId,
sequenceId,
unitId,
intl,
onNext,
onPrevious,
fetchState,
displayName,
showCompletion,
isTimeLimited,
savePosition,
bannerText,
gatedContent,
position,
items,
lmsWebUrl,
} = props;
const loaded = fetchState === 'loaded';
const unitIds = useMemo(() => items.map(({ id }) => id), [items]);
useEffect(() => {
props.fetchSequenceMetadata(sequenceId);
}, [sequenceId]);
useEffect(() => {
if (savePosition) {
const activeUnitIndex = unitIds.indexOf(unitId);
props.saveSequencePosition(courseUsageKey, sequenceId, activeUnitIndex);
}
}, [unitId]);
useEffect(() => {
if (loaded && !unitId) {
// The position may be null, in which case we'll just assume 0.
const unitIndex = position || 0;
const nextUnitId = unitIds[unitIndex];
history.push(`/course/${courseUsageKey}/${sequenceId}/${nextUnitId}`);
}
}, [loaded, unitId]);
const handleUnitNavigation = useCallback((nextUnitId) => {
props.checkBlockCompletion(courseUsageKey, sequenceId, unitId);
history.push(`/course/${courseUsageKey}/${sequenceId}/${nextUnitId}`);
}, [courseUsageKey, sequenceId]);
// Exam redirect
useEffect(() => {
if (isTimeLimited) {
global.location.href = lmsWebUrl;
}
}, [isTimeLimited]);
const isLoading = !loaded || !unitId || isTimeLimited;
return (
<>
<AlertList topic="sequence" />
<div className="course-content-container">
{isLoading ? (
<PageLoading
srMessage={intl.formatMessage(messages['learn.loading.learning.sequence'])}
/>
) : (
<Sequence
id={sequenceId}
courseUsageKey={courseUsageKey}
courseId={courseId}
unitIds={unitIds}
displayName={displayName}
activeUnitId={unitId}
showCompletion={showCompletion}
isTimeLimited={isTimeLimited}
isGated={gatedContent.gated}
savePosition={savePosition}
bannerText={bannerText}
onNext={onNext}
onPrevious={onPrevious}
onNavigateUnit={handleUnitNavigation}
prerequisite={{
id: gatedContent.prereqId,
name: gatedContent.gatedSectionName,
}}
/>
)}
</div>
</>
);
}
SequenceContainer.propTypes = {
onNext: PropTypes.func.isRequired,
onPrevious: PropTypes.func.isRequired,
courseUsageKey: PropTypes.string.isRequired,
courseId: PropTypes.string.isRequired,
sequenceId: PropTypes.string.isRequired,
unitId: PropTypes.string,
intl: intlShape.isRequired,
items: PropTypes.arrayOf(PropTypes.shape({
id: PropTypes.string,
})),
gatedContent: PropTypes.shape({
gated: PropTypes.bool,
gatedSectionName: PropTypes.string,
prereqId: PropTypes.string,
}),
checkBlockCompletion: PropTypes.func.isRequired,
fetchSequenceMetadata: PropTypes.func.isRequired,
saveSequencePosition: PropTypes.func.isRequired,
savePosition: PropTypes.bool,
lmsWebUrl: PropTypes.string,
position: PropTypes.number,
fetchState: PropTypes.string,
displayName: PropTypes.string,
showCompletion: PropTypes.bool,
isTimeLimited: PropTypes.bool,
bannerText: PropTypes.string,
};
SequenceContainer.defaultProps = {
unitId: undefined,
gatedContent: undefined,
showCompletion: false,
lmsWebUrl: undefined,
position: undefined,
fetchState: undefined,
displayName: undefined,
isTimeLimited: undefined,
bannerText: undefined,
savePosition: undefined,
items: [],
};
export default connect(
(state, props) => ({
...state.courseBlocks.blocks[props.sequenceId],
}),
{
fetchSequenceMetadata,
checkBlockCompletion,
saveSequencePosition,
},
)(injectIntl(SequenceContainer));

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -1,175 +0,0 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage } from '@edx/frontend-platform/i18n';
import LearnerQuote1 from './assets/learner-quote.png';
import LearnerQuote2 from './assets/learner-quote2.png';
import VerifiedCert from './assets/verified-cert.png';
export default class CourseSock extends Component {
constructor(props) {
super(props);
this.verifiedMode = props.verifiedMode;
this.state = { showUpsell: false };
}
handleClick = () => {
this.setState(state => ({
showUpsell: !state.showUpsell,
}));
}
render() {
const buttonClass = this.state.showUpsell ? 'btn-success' : 'btn-outline-success';
return (
<div className="verification-sock container py-5">
<div className="d-flex justify-content-center">
<button type="button" aria-expanded="false" className={`btn ${buttonClass}`} onClick={this.handleClick}>
<FormattedMessage
id="coursesock.upsell.heading"
defaultMessage="Learn About Verified Certificates"
description="The heading for the upsell dialog"
/>
</button>
</div>
{this.state.showUpsell && (
<div className="d-flex justify-content-around">
<div className="mt-3">
<h2 className="font-weight-lighter">
<FormattedMessage
id="coursesock.upsell.verifiedcert"
defaultMessage="edX Verified Certificate"
/>
</h2>
<h3>
<FormattedMessage
id="coursesock.upsell.why"
defaultMessage="Why upgrade?"
/>
</h3>
<ul>
<li><FormattedMessage
id="coursesock.upsell.reason1"
defaultMessage="Official proof of completion"
/>
</li>
<li><FormattedMessage
id="coursesock.upsell.reason2"
defaultMessage="Easily shareable certificate"
/>
</li>
<li><FormattedMessage
id="coursesock.upsell.reason3"
defaultMessage="Proven motivator to complete the course"
/>
</li>
<li><FormattedMessage
id="coursesock.upsell.reason4"
defaultMessage="Certificate purchases help edX continue to offer free courses"
/>
</li>
</ul>
<h3><FormattedMessage
id="coursesock.upsell.howtitle"
defaultMessage="How it works"
/>
</h3>
<ul>
<li><FormattedMessage
id="coursesock.upsell.how1"
defaultMessage="Pay the Verified Certificate upgrade fee"
/>
</li>
<li><FormattedMessage
id="coursesock.upsell.how2"
defaultMessage="Verify your identity with a webcam and government-issued ID"
/>
</li>
<li><FormattedMessage
id="coursesock.upsell.how3"
defaultMessage="Study hard and pass the course"
/>
</li>
<li><FormattedMessage
id="coursesock.upsell.how4"
defaultMessage="Share your certificate with friends, employers, and others"
/>
</li>
</ul>
<h3><FormattedMessage
id="coursesock.upsell.storytitle"
defaultMessage="edX Learner Stories"
/>
</h3>
<div className="d-flex align-items-center my-4">
<img style={{ maxWidth: '4rem' }} alt="Christina Fong" src={LearnerQuote1} />
<div className="w-50 px-4">
<FormattedMessage
id="coursesock.upsell.story1"
defaultMessage="My certificate has helped me showcase my knowledge on my
resume - I feel like this certificate could really help me land
my dream job!"
/>
<br />
<strong>&mdash; <FormattedMessage
id="coursesock.upsell.learner"
description="Name of learner"
defaultMessage="{ name }, edX Learner"
values={{ name: 'Christina Fong' }}
/>
</strong>
</div>
</div>
<div className="d-flex align-items-center my-2">
<img style={{ maxWidth: '4rem' }} alt="Chery Troell" src={LearnerQuote2} />
<div className="w-50 px-4">
<FormattedMessage
id="coursesock.upsell.story2"
defaultMessage="I wanted to include a verified certificate on my resume and my profile to
illustrate that I am working towards this goal I have and that I have
achieved something while I was unemployed."
/>
<br />
<strong>&mdash; <FormattedMessage
id="coursesock.upsell.learner"
description="Name of learner"
defaultMessage="{ name }, edX Learner"
values={{ name: 'Cheryl Troell' }}
/>
</strong>
</div>
</div>
</div>
<div className="d-flex flex-column justify-content-between">
<img alt="Example Certificate" src={VerifiedCert} />
<a href={this.verifiedMode.upgradeUrl} className="btn btn-success btn-lg btn-upgrade focusable" data-creative="original_sock" data-position="sock">
<FormattedMessage
id="coursesock.upsell.upgrade"
defaultMessage="Upgrade ({symbol}{price} {currency})"
values={{
symbol: this.verifiedMode.currencySymbol,
price: this.verifiedMode.price,
currency: this.verifiedMode.currency,
}}
/>
</a>
</div>
</div>
)}
</div>
);
}
}
CourseSock.propTypes = {
verifiedMode: PropTypes.shape({
price: PropTypes.number,
currency: PropTypes.string,
currencySymbol: PropTypes.string,
sku: PropTypes.string,
upgradeUrl: PropTypes.string,
}),
};
CourseSock.defaultProps = {
verifiedMode: null,
};

View File

@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="1168px" height="540px" viewBox="0 0 1168 540" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 53.2 (72643) - https://sketchapp.com -->
<title>logo</title>
<desc>Created with Sketch.</desc>
<g id="logo" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<polygon id="Path" fill="#209FDA" fill-rule="nonzero" points="1166.81993 85.5 1166.81993 2.84217094e-14 953.759925 2.84217094e-14 953.759925 85.5 1002.17993 85.5 915.859925 191.98 829.459925 85.5 878.099925 85.5 878.099925 2.84217094e-14 718.919925 2.84217094e-14 718.919925 95.72 856.479925 265.26 718.919925 434.96 718.919925 452.02 784.499925 452.02 784.499925 539.64 878.099925 539.64 878.099925 452.02 823.919925 452.02 915.919925 338.52 915.939925 338.52 1008.03993 452.02 953.759925 452.02 953.759925 539.64 1166.81993 539.64 1166.81993 452.02 1126.85993 452.02 975.319925 265.26 1121.01993 85.5"></polygon>
<polygon id="Path" fill="#026BA4" fill-rule="nonzero" points="664.019925 7.10542736e-15 664.019925 85.5 710.619925 85.5 718.919925 95.72 718.919925 7.10542736e-15"></polygon>
<polygon id="Path" fill="#026BA4" fill-rule="nonzero" points="718.919925 452.02 718.919925 434.96 705.079925 452.02 664.019925 452.02 664.019925 539.64 784.499925 539.64 784.499925 452.02"></polygon>
<path d="M321.999925,411.86 L397.659925,411.86 C388.805702,433.829527 376.258024,454.122269 360.559925,471.86 C344.364089,454.216816 331.320914,433.921419 321.999925,411.86" id="Path" fill="#78212E" fill-rule="nonzero"></path>
<path d="M360.559925,189.28 C338.58337,213.190393 322.501981,241.908137 313.599925,273.14 C317.134915,280.039338 320.007771,287.25831 322.179925,294.7 L397.059925,294.7 C399.306706,287.354671 402.25356,280.242036 405.859925,273.46 C397.464721,242.277678 381.959326,213.464341 360.559925,189.28 Z M322.179925,294.7 C328.784599,317.438017 328.978396,341.558795 322.739925,364.4 L396.399925,364.4 C389.855554,341.597488 390.06397,317.386469 396.999925,294.7 L322.179925,294.7 Z M322.179925,294.7 L308.679925,294.7 C304.690779,317.752715 304.575868,341.309464 308.339925,364.4 L322.739925,364.4 C328.978396,341.558795 328.784599,317.438017 322.179925,294.7 L322.179925,294.7 Z" id="Shape" fill="#78212E" fill-rule="nonzero"></path>
<path d="M710.619925,85.5 L664.019925,85.5 L664.019925,0.02 L576.019925,0.02 L576.019925,85.5 L632.859925,85.5 L632.859925,159.2 C598.417874,134.487772 557.04992,121.286425 514.659925,121.48 C456.044663,121.405246 400.107354,146.01621 360.559925,189.28 C381.937732,213.470272 397.422343,242.283149 405.799925,273.46 C426.944121,233.500977 468.451514,208.51034 513.659925,208.52 C581.059925,208.52 632.879925,263.16 632.879925,330.52 L632.879925,331.2 C632.539925,398.28 580.879925,452.56 513.659925,452.56 C468.477451,452.593197 426.976426,427.652566 405.799925,387.74 L405.799925,387.74 C401.869213,380.340239 398.718926,372.551658 396.399925,364.5 L308.399925,364.5 C309.686934,372.450225 311.443338,380.317312 313.659925,388.06 C315.970162,396.190434 318.775397,404.171995 322.059925,411.96 L397.659925,411.96 C388.805702,433.929527 376.258024,454.222269 360.559925,471.96 C400.107354,515.22379 456.044663,539.834754 514.659925,539.76 C571.465111,540.091874 625.745998,516.316729 664.019925,474.34 L664.019925,452.04 L705.059925,452.04 L718.899925,434.96 L718.899925,95.74 L710.619925,85.5 Z M632.879925,501.9 L632.879925,539.74 L664.019925,539.74 L664.019925,474.18 C654.623775,484.469293 644.18821,493.758755 632.879925,501.9 L632.879925,501.9 Z M313.599925,273.14 C311.569597,280.231983 309.927163,287.429316 308.679925,294.7 L322.179925,294.7 C320.007771,287.25831 317.134915,280.039338 313.599925,273.14 L313.599925,273.14 Z" id="Shape" fill="#8A8C8F" fill-rule="nonzero"></path>
<path d="M410.399925,294.7 C409.199925,287.5 407.659925,280.4 405.799925,273.46 C402.19356,280.242036 399.246706,287.354671 396.999925,294.7 C390.06397,317.386469 389.855554,341.597488 396.399925,364.4 L410.719925,364.4 C414.264276,341.293291 414.156293,317.77319 410.399925,294.7 L410.399925,294.7 Z M209.059925,121.48 C107.422724,121.487508 20.5081632,194.571683 3.05992537,294.7 L91.3999254,294.7 C107.135726,243.467257 154.465065,208.503753 208.059925,208.52 C252.638644,208.335148 293.496156,233.351373 313.599925,273.14 C322.501981,241.908137 338.58337,213.190393 360.559925,189.28 C322.206855,145.880863 266.976617,121.163964 209.059925,121.48 L209.059925,121.48 Z M297.479925,411.86 C275.077969,437.877726 242.392659,452.761934 208.059925,452.58 C153.691226,452.598435 105.87164,416.63791 90.7999254,364.4 L308.339925,364.4 C304.575868,341.309464 304.690779,317.752715 308.679925,294.7 L3.05992537,294.7 C-0.902504563,317.755068 -1.01739385,341.307372 2.71992537,364.4 L2.71992537,364.4 C19.3292424,465.441984 106.661918,539.594765 209.059925,539.6 C266.986094,539.900862 322.217868,515.161403 360.559925,471.74 C344.364089,454.096816 331.320914,433.801419 321.999925,411.74 L297.479925,411.86 Z" id="Shape" fill="#B72768" fill-rule="nonzero"></path>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 5.0 KiB

View File

@@ -1,174 +0,0 @@
/* eslint-disable no-use-before-define */
import React, {
useEffect, useContext, Suspense, useState,
} from 'react';
import PropTypes from 'prop-types';
import { injectIntl, intlShape, FormattedMessage } from '@edx/frontend-platform/i18n';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faChevronLeft, faChevronRight } from '@fortawesome/free-solid-svg-icons';
import { Button } from '@edx/paragon';
import Unit from './Unit';
import SequenceNavigation from './SequenceNavigation';
import PageLoading from '../../PageLoading';
import messages from './messages';
import UserMessagesContext from '../../user-messages/UserMessagesContext';
const ContentLock = React.lazy(() => import('./content-lock'));
function Sequence({
courseUsageKey,
unitIds,
displayName,
showCompletion,
onNext,
onPrevious,
onNavigateUnit,
isGated,
prerequisite,
activeUnitId,
bannerText,
intl,
}) {
const handleNext = () => {
const nextIndex = unitIds.indexOf(activeUnitId) + 1;
if (nextIndex < unitIds.length) {
const newUnitId = unitIds[nextIndex];
handleNavigate(newUnitId);
} else {
onNext();
}
};
const handlePrevious = () => {
const previousIndex = unitIds.indexOf(activeUnitId) - 1;
if (previousIndex >= 0) {
const newUnitId = unitIds[previousIndex];
handleNavigate(newUnitId);
} else {
onPrevious();
}
};
const handleNavigate = (unitId) => {
onNavigateUnit(unitId);
};
const { add, remove } = useContext(UserMessagesContext);
useEffect(() => {
let id = null;
if (bannerText) {
id = add({
code: null,
dismissible: false,
text: bannerText,
type: 'info',
topic: 'sequence',
});
}
return () => {
if (id) {
remove(id);
}
};
}, [bannerText]);
const [unitHasLoaded, setUnitHasLoaded] = useState(false);
const handleUnitLoaded = () => {
setUnitHasLoaded(true);
};
useEffect(() => {
setUnitHasLoaded(false);
}, [activeUnitId]);
return (
<>
<SequenceNavigation
className="mb-4"
onNext={handleNext}
onNavigate={handleNavigate}
onPrevious={handlePrevious}
unitIds={unitIds}
activeUnitId={activeUnitId}
isLocked={isGated}
showCompletion={showCompletion}
/>
<div className="flex-grow-1">
{isGated && (
<Suspense
fallback={(
<PageLoading
srMessage={intl.formatMessage(messages['learn.loading.content.lock'])}
/>
)}
>
<ContentLock
courseUsageKey={courseUsageKey}
sectionName={displayName}
prereqSectionName={prerequisite.name}
prereqId={prerequisite.id}
/>
</Suspense>
)}
{!isGated && (
<Unit
key={activeUnitId}
id={activeUnitId}
onLoaded={handleUnitLoaded}
/>
)}
</div>
{unitHasLoaded ? (
<div className="unit-content-container below-unit-navigation">
<Button
className="btn-outline-secondary previous-button w-25 mr-2"
onClick={handlePrevious}
>
<FontAwesomeIcon icon={faChevronLeft} className="mr-2" size="sm" />
<FormattedMessage
id="learn.sequence.navigation.after.unit.previous"
description="The button to go to the previous unit"
defaultMessage="Previous"
/>
</Button>
<Button
className="btn-outline-primary next-button w-75"
onClick={handleNext}
>
<FormattedMessage
id="learn.sequence.navigation.after.unit.next"
description="The button to go to the next unit"
defaultMessage="Next"
/>
<FontAwesomeIcon icon={faChevronRight} className="ml-2" size="sm" />
</Button>
</div>
) : null}
</>
);
}
Sequence.propTypes = {
activeUnitId: PropTypes.string.isRequired,
courseUsageKey: PropTypes.string.isRequired,
displayName: PropTypes.string.isRequired,
intl: intlShape.isRequired,
isGated: PropTypes.bool.isRequired,
onNavigateUnit: PropTypes.func,
onNext: PropTypes.func.isRequired,
onPrevious: PropTypes.func.isRequired,
showCompletion: PropTypes.bool.isRequired,
prerequisite: PropTypes.shape({
name: PropTypes.string,
id: PropTypes.string,
}).isRequired,
unitIds: PropTypes.arrayOf(PropTypes.string).isRequired,
bannerText: PropTypes.string,
};
Sequence.defaultProps = {
onNavigateUnit: null,
bannerText: undefined,
};
export default injectIntl(Sequence);

View File

@@ -1,69 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Button } from '@edx/paragon';
import classNames from 'classnames';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faChevronLeft, faChevronRight } from '@fortawesome/free-solid-svg-icons';
import { FormattedMessage } from '@edx/frontend-platform/i18n';
import UnitButton from './UnitButton';
export default function SequenceNavigation({
onNext,
onPrevious,
onNavigate,
unitIds,
isLocked,
showCompletion,
activeUnitId,
className,
}) {
const unitButtons = unitIds.map(unitId => (
<UnitButton
key={unitId}
unitId={unitId}
isActive={activeUnitId === unitId}
showCompletion={showCompletion}
onClick={onNavigate}
/>
));
return (
<nav className={classNames('sequence-navigation', className)}>
<Button className="previous-btn" onClick={onPrevious}>
<FontAwesomeIcon icon={faChevronLeft} className="mr-2" size="sm" />
<FormattedMessage
defaultMessage="Previous"
id="learn.sequence.navigation.previous.button"
description="The Previous button in the sequence nav"
/>
</Button>
{isLocked ? <UnitButton type="lock" isActive /> : unitButtons}
<Button className="next-btn" onClick={onNext}>
<FormattedMessage
defaultMessage="Next"
id="learn.sequence.navigation.next.button"
description="The Next button in the sequence nav"
/>
<FontAwesomeIcon icon={faChevronRight} className="ml-2" size="sm" />
</Button>
</nav>
);
}
SequenceNavigation.propTypes = {
className: PropTypes.string,
onNext: PropTypes.func.isRequired,
onPrevious: PropTypes.func.isRequired,
onNavigate: PropTypes.func.isRequired,
isLocked: PropTypes.bool.isRequired,
showCompletion: PropTypes.bool.isRequired,
unitIds: PropTypes.arrayOf(PropTypes.string).isRequired,
activeUnitId: PropTypes.string.isRequired,
};
SequenceNavigation.defaultProps = {
className: null,
};

View File

@@ -1,90 +0,0 @@
import React, { useRef, useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { getConfig } from '@edx/frontend-platform';
import { connect } from 'react-redux';
import BookmarkButton from './bookmark/BookmarkButton';
import { addBookmark, removeBookmark } from '../../data/course-blocks';
function Unit({
bookmarked,
bookmarkedUpdateState,
displayName,
onLoaded,
id,
...props
}) {
const iframeRef = useRef(null);
const iframeUrl = `${getConfig().LMS_BASE_URL}/xblock/${id}?show_title=0&show_bookmark_button=0`;
const [iframeHeight, setIframeHeight] = useState(0);
const [hasLoaded, setHasLoaded] = useState(false);
useEffect(() => {
global.onmessage = (event) => {
const { type, payload } = event.data;
if (type === 'plugin.resize') {
setIframeHeight(payload.height);
if (!hasLoaded && iframeHeight === 0 && payload.height > 0) {
setHasLoaded(true);
if (onLoaded) {
onLoaded();
}
}
}
};
}, []);
const toggleBookmark = () => {
if (bookmarked) {
props.removeBookmark(id);
} else {
props.addBookmark(id);
}
};
return (
<>
<div className="unit-content-container">
<h2 className="mb-0 h4">{displayName}</h2>
<BookmarkButton
onClick={toggleBookmark}
isBookmarked={bookmarked}
isProcessing={bookmarkedUpdateState === 'loading'}
/>
</div>
<iframe
id="unit-iframe"
title={displayName}
ref={iframeRef}
src={iframeUrl}
allowFullScreen
height={iframeHeight}
scrolling="no"
referrerPolicy="origin"
/>
</>
);
}
Unit.propTypes = {
addBookmark: PropTypes.func.isRequired,
bookmarked: PropTypes.bool,
bookmarkedUpdateState: PropTypes.string,
displayName: PropTypes.string.isRequired,
id: PropTypes.string.isRequired,
removeBookmark: PropTypes.func.isRequired,
onLoaded: PropTypes.func,
};
Unit.defaultProps = {
bookmarked: false,
bookmarkedUpdateState: undefined,
onLoaded: undefined,
};
const mapStateToProps = (state, props) => state.courseBlocks.blocks[props.id] || {};
export default connect(mapStateToProps, {
addBookmark,
removeBookmark,
})(Unit);

View File

@@ -1,68 +0,0 @@
import React, { useCallback } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import classNames from 'classnames';
import { Button } from '@edx/paragon';
import UnitIcon from './UnitIcon';
import CompleteIcon from './CompleteIcon';
import BookmarkFilledIcon from './bookmark/BookmarkFilledIcon';
function UnitButton({
onClick,
displayName,
contentType,
isActive,
bookmarked,
complete,
showCompletion,
unitId,
}) {
const handleClick = useCallback(() => {
onClick(unitId);
});
return (
<Button
className={classNames({
active: isActive,
complete: showCompletion && complete,
})}
onClick={handleClick}
title={displayName}
>
<UnitIcon type={contentType} />
{showCompletion && complete ? <CompleteIcon size="sm" className="text-success ml-2" /> : null}
{bookmarked ? (
<BookmarkFilledIcon
className="text-primary small position-absolute"
style={{ top: '-3px', right: '5px' }}
/>
) : null}
</Button>
);
}
UnitButton.propTypes = {
unitId: PropTypes.string.isRequired,
isActive: PropTypes.bool,
bookmarked: PropTypes.bool,
complete: PropTypes.bool,
showCompletion: PropTypes.bool,
onClick: PropTypes.func.isRequired,
displayName: PropTypes.string.isRequired,
contentType: PropTypes.string.isRequired,
};
UnitButton.defaultProps = {
isActive: false,
bookmarked: false,
complete: false,
showCompletion: true,
};
const mapStateToProps = (state, props) => ({
...state.courseBlocks.blocks[props.unitId],
});
export default connect(mapStateToProps)(UnitButton);

View File

@@ -1,54 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import { StatefulButton } from '@edx/paragon';
import { FormattedMessage } from '@edx/frontend-platform/i18n';
import BookmarkOutlineIcon from './BookmarkOutlineIcon';
import BookmarkFilledIcon from './BookmarkFilledIcon';
const addBookmarkLabel = (
<FormattedMessage
id="unit.bookmark.button.add.bookmark"
defaultMessage="Bookmark this page"
description="The button to bookmark a page"
/>
);
const hasBookmarkLabel = (
<FormattedMessage
id="unit.bookmark.button.remove.bookmark"
defaultMessage="Bookmarked"
description="The button to show a page is bookmarked and the button to remove that bookmark"
/>
);
export default function BookmarkButton({ onClick, isBookmarked, isProcessing }) {
const bookmarkState = isBookmarked ? 'bookmarked' : 'default';
const state = isProcessing ? `${bookmarkState}Processing` : bookmarkState;
return (
<StatefulButton
className="btn-link px-1 ml-n1 btn-sm"
onClick={onClick}
state={state}
disabledStates={['defaultProcessing', 'bookmarkedProcessing']}
labels={{
default: addBookmarkLabel,
defaultProcessing: addBookmarkLabel,
bookmarked: hasBookmarkLabel,
bookmarkedProcessing: hasBookmarkLabel,
}}
icons={{
default: <BookmarkOutlineIcon className="text-primary" />,
defaultProcessing: <BookmarkOutlineIcon className="text-primary" />,
bookmarked: <BookmarkFilledIcon className="text-primary" />,
bookmarkedProcessing: <BookmarkFilledIcon className="text-primary" />,
}}
/>
);
}
BookmarkButton.propTypes = {
onClick: PropTypes.func.isRequired,
isBookmarked: PropTypes.bool.isRequired,
isProcessing: PropTypes.bool.isRequired,
};

View File

@@ -1,7 +0,0 @@
import React from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faBookmark } from '@fortawesome/free-solid-svg-icons';
export default function BookmarkFilledIcon(props) {
return <FontAwesomeIcon icon={faBookmark} {...props} />;
}

View File

@@ -1,7 +0,0 @@
import React from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faBookmark } from '@fortawesome/free-regular-svg-icons';
export default function BookmarkOutlineIcon(props) {
return <FontAwesomeIcon icon={faBookmark} {...props} />;
}

View File

@@ -1,109 +0,0 @@
import { getConfig, camelCaseObject } from '@edx/frontend-platform';
import { getAuthenticatedHttpClient, getAuthenticatedUser } from '@edx/frontend-platform/auth';
export async function getCourseBlocks(courseUsageKey) {
const { username } = getAuthenticatedUser();
const url = new URL(`${getConfig().LMS_BASE_URL}/api/courses/v2/blocks/`);
url.searchParams.append('course_id', courseUsageKey);
url.searchParams.append('username', username);
url.searchParams.append('depth', 3);
url.searchParams.append('requested_fields', 'children,show_gated_sections');
const { data } = await getAuthenticatedHttpClient().get(url.href, {});
// Camelcase block objects (leave blockId keys alone)
const blocks = Object.entries(data.blocks).reduce((acc, [key, value]) => {
acc[key] = camelCaseObject(value);
return acc;
}, {});
// Next go through the blocksList again - now that we've added them all to the blocks map - and
// append a parent ID to every child found in every `children` list, using the blocks map to find
// them.
Object.values(blocks).forEach((block) => {
if (Array.isArray(block.children)) {
const parentId = block.id;
block.children.forEach((childBlockId) => {
blocks[childBlockId].parentId = parentId;
});
}
});
const processedData = camelCaseObject(data);
processedData.blocks = blocks;
return processedData;
}
export async function getSequenceMetadata(sequenceId) {
const { data } = await getAuthenticatedHttpClient()
.get(`${getConfig().LMS_BASE_URL}/api/courseware/sequence/${sequenceId}`, {});
const camelCasedData = camelCaseObject(data);
camelCasedData.items = camelCasedData.items.map((item) => {
const processedItem = camelCaseObject(item);
processedItem.contentType = processedItem.type;
delete processedItem.type;
return processedItem;
});
// Position comes back from the server 1-indexed. Adjust here.
camelCasedData.position = camelCasedData.position ? camelCasedData.position - 1 : 0;
return camelCasedData;
}
const getSequenceXModuleHandlerUrl = (courseUsageKey, sequenceId) => `${getConfig().LMS_BASE_URL}/courses/${courseUsageKey}/xblock/${sequenceId}/handler/xmodule_handler`;
export async function updateSequencePosition(courseUsageKey, sequenceId, position) {
// Post data sent to this endpoint must be url encoded
// TODO: Remove the need for this to be the case.
// TODO: Ensure this usage of URLSearchParams is working in Internet Explorer
const urlEncoded = new URLSearchParams();
// Position is 1-indexed on the server and 0-indexed in this app. Adjust here.
urlEncoded.append('position', position + 1);
const requestConfig = {
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
};
const { data } = await getAuthenticatedHttpClient().post(
`${getSequenceXModuleHandlerUrl(courseUsageKey, sequenceId)}/goto_position`,
urlEncoded.toString(),
requestConfig,
);
return data;
}
export async function getBlockCompletion(courseUsageKey, sequenceId, usageKey) {
// Post data sent to this endpoint must be url encoded
// TODO: Remove the need for this to be the case.
// TODO: Ensure this usage of URLSearchParams is working in Internet Explorer
const urlEncoded = new URLSearchParams();
urlEncoded.append('usage_key', usageKey);
const requestConfig = {
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
};
const { data } = await getAuthenticatedHttpClient().post(
`${getSequenceXModuleHandlerUrl(courseUsageKey, sequenceId)}/get_completion`,
urlEncoded.toString(),
requestConfig,
);
if (data.complete) {
return true;
}
return false;
}
const bookmarksBaseUrl = `${getConfig().LMS_BASE_URL}/api/bookmarks/v1/bookmarks/`;
export async function createBookmark(usageId) {
return getAuthenticatedHttpClient().post(bookmarksBaseUrl, { usage_id: usageId });
}
export async function deleteBookmark(usageId) {
const { username } = getAuthenticatedUser();
return getAuthenticatedHttpClient().delete(`${bookmarksBaseUrl}${username},${usageId}/`);
}

View File

@@ -1,20 +0,0 @@
export {
getCourseBlocks,
getSequenceMetadata,
updateSequencePosition,
getBlockCompletion,
createBookmark,
deleteBookmark,
} from './api';
export {
reducer,
courseBlocksShape,
} from './slice';
export {
fetchCourseBlocks,
fetchSequenceMetadata,
checkBlockCompletion,
saveSequencePosition,
addBookmark,
removeBookmark,
} from './thunks';

View File

@@ -1,142 +0,0 @@
/* eslint-disable no-param-reassign */
import { createSlice } from '@reduxjs/toolkit';
import PropTypes from 'prop-types';
const blocksSlice = createSlice({
name: 'blocks',
initialState: {
fetchState: null,
root: null,
blocks: {},
},
reducers: {
/**
* fetchCourseBlocks
* This routine is responsible for fetching all blocks in a course.
*/
fetchCourseBlocksRequest: (draftState) => {
draftState.fetchState = 'loading';
},
fetchCourseBlocksSuccess: (draftState, { payload }) => ({
...payload,
fetchState: 'loaded',
loaded: true,
}),
fetchCourseBlocksFailure: (draftState) => {
draftState.fetchState = 'failed';
},
/**
* fetchBlockMetadata
* This routine is responsible for fetching metadata for any kind of
* block (sequential, vertical or any other block) and merging that
* data with what is in the store. Currently used for:
*
* - fetchSequenceMetadata
* - checkBlockCompletion (Vertical blocks)
*/
fetchBlockMetadataRequest: (draftState, action) => {
const { blockId } = action.payload;
if (!draftState.blocks[blockId]) {
draftState.blocks[blockId] = {};
}
draftState.blocks[blockId].fetchState = 'loading';
},
fetchBlockMetadataSuccess: (draftState, action) => {
const { blockId, metadata, relatedBlocksMetadata } = action.payload;
if (!draftState.blocks[blockId]) {
draftState.blocks[blockId] = {};
}
draftState.blocks[blockId] = {
...draftState.blocks[blockId],
...metadata,
fetchState: 'loaded',
loaded: true,
};
if (relatedBlocksMetadata) {
relatedBlocksMetadata.forEach((blockMetadata) => {
if (draftState.blocks[blockMetadata.id] === undefined) {
draftState.blocks[blockMetadata.id] = {};
}
draftState.blocks[blockMetadata.id] = {
...draftState.blocks[blockMetadata.id],
...blockMetadata,
};
});
}
},
fetchBlockMetadataFailure: (draftState, action) => {
const { blockId } = action.payload;
if (!draftState.blocks[blockId]) {
draftState.blocks[blockId] = {};
}
draftState.blocks[blockId].fetchState = 'failure';
},
/**
* updateBlock
* This routine is responsible for CRUD operations on block properties.
* Updates to blocks are handled in an optimistic way applying the update
* to the store at request time and then reverting it if the update fails.
*
* TODO: It may be helpful to add a flag to be optimistic or not.
*
* The update state of a property is added to the block in the store with
* a dynamic property name: ${propertyToUpdate}UpdateState.
* (e.g. bookmarkedUpdateState)
*
* Used in:
* - saveSequencePosition
* - addBookmark
* - removeBookmark
*/
updateBlockRequest: (draftState, action) => {
const { blockId, propertyToUpdate, updateValue } = action.payload;
const updateStateKey = `${propertyToUpdate}UpdateState`;
if (!draftState.blocks[blockId]) {
draftState.blocks[blockId] = {};
}
draftState.blocks[blockId][updateStateKey] = 'loading';
draftState.blocks[blockId][propertyToUpdate] = updateValue;
},
updateBlockSuccess: (draftState, action) => {
const { blockId, propertyToUpdate, updateValue } = action.payload;
const updateStateKey = `${propertyToUpdate}UpdateState`;
if (!draftState.blocks[blockId]) {
draftState.blocks[blockId] = {};
}
draftState.blocks[blockId][updateStateKey] = 'updated';
draftState.blocks[blockId][propertyToUpdate] = updateValue;
},
updateBlockFailure: (draftState, action) => {
const { blockId, propertyToUpdate, initialValue } = action.payload;
const updateStateKey = `${propertyToUpdate}UpdateState`;
if (!draftState.blocks[blockId]) {
draftState.blocks[blockId] = {};
}
draftState.blocks[blockId][updateStateKey] = 'failed';
draftState.blocks[blockId][propertyToUpdate] = initialValue;
},
},
});
export const {
fetchCourseBlocksRequest,
fetchCourseBlocksSuccess,
fetchCourseBlocksFailure,
fetchBlockMetadataRequest,
fetchBlockMetadataSuccess,
fetchBlockMetadataFailure,
updateBlockRequest,
updateBlockSuccess,
updateBlockFailure,
} = blocksSlice.actions;
export const { reducer } = blocksSlice;
export const courseBlocksShape = PropTypes.objectOf(PropTypes.shape({
id: PropTypes.string.isRequired,
displayName: PropTypes.string.isRequired,
children: PropTypes.arrayOf(PropTypes.string),
parentId: PropTypes.string,
}));

View File

@@ -1,124 +0,0 @@
import {
fetchCourseBlocksRequest,
fetchCourseBlocksSuccess,
fetchCourseBlocksFailure,
fetchBlockMetadataRequest,
fetchBlockMetadataSuccess,
fetchBlockMetadataFailure,
updateBlockRequest,
updateBlockSuccess,
updateBlockFailure,
} from './slice';
import {
getCourseBlocks,
getSequenceMetadata,
getBlockCompletion,
updateSequencePosition,
createBookmark,
deleteBookmark,
} from './api';
export function fetchCourseBlocks(courseUsageKey) {
return async (dispatch) => {
dispatch(fetchCourseBlocksRequest(courseUsageKey));
try {
const courseBlocks = await getCourseBlocks(courseUsageKey);
dispatch(fetchCourseBlocksSuccess(courseBlocks));
} catch (error) {
dispatch(fetchCourseBlocksFailure(error));
}
};
}
export function fetchSequenceMetadata(sequenceBlockId) {
return async (dispatch) => {
dispatch(fetchBlockMetadataRequest({ blockId: sequenceBlockId }));
try {
const sequenceMetadata = await getSequenceMetadata(sequenceBlockId);
dispatch(fetchBlockMetadataSuccess({
blockId: sequenceBlockId,
metadata: sequenceMetadata,
relatedBlocksMetadata: sequenceMetadata.items,
}));
} catch (error) {
dispatch(fetchBlockMetadataFailure({ blockId: sequenceBlockId }, error));
}
};
}
export function checkBlockCompletion(courseUsageKey, sequenceId, unitId) {
return async (dispatch, getState) => {
const { courseBlocks } = getState();
if (courseBlocks.blocks[unitId].complete) {
return; // do nothing. Things don't get uncompleted after they are completed.
}
const commonPayload = { blockId: unitId, fetchType: 'completion' };
dispatch(fetchBlockMetadataRequest(commonPayload));
try {
const isComplete = await getBlockCompletion(courseUsageKey, sequenceId, unitId);
dispatch(fetchBlockMetadataSuccess({
...commonPayload,
metadata: {
complete: isComplete,
},
}));
} catch (error) {
dispatch(fetchBlockMetadataFailure(commonPayload, error));
}
};
}
export function saveSequencePosition(courseUsageKey, sequenceId, position) {
return async (dispatch, getState) => {
const { courseBlocks } = getState();
const actionPayload = {
blockId: sequenceId,
propertyToUpdate: 'position',
updateValue: position,
initialValue: courseBlocks.blocks[sequenceId].position,
};
dispatch(updateBlockRequest(actionPayload));
try {
await updateSequencePosition(courseUsageKey, sequenceId, position);
dispatch(updateBlockSuccess(actionPayload));
} catch (error) {
dispatch(updateBlockFailure(actionPayload));
}
};
}
export function addBookmark(unitId) {
return async (dispatch) => {
const actionPayload = {
blockId: unitId,
propertyToUpdate: 'bookmarked',
updateValue: true,
initialValue: false,
};
dispatch(updateBlockRequest(actionPayload));
try {
await createBookmark(unitId);
dispatch(updateBlockSuccess(actionPayload));
} catch (error) {
dispatch(updateBlockFailure(actionPayload));
}
};
}
export function removeBookmark(unitId) {
return async (dispatch) => {
const actionPayload = {
blockId: unitId,
propertyToUpdate: 'bookmarked',
updateValue: false,
initialValue: true,
};
dispatch(updateBlockRequest(actionPayload));
try {
await deleteBookmark(unitId);
dispatch(updateBlockSuccess(actionPayload));
} catch (error) {
dispatch(updateBlockFailure(actionPayload));
}
};
}

View File

@@ -1,10 +0,0 @@
/* eslint-disable import/prefer-default-export */
import { getConfig, camelCaseObject } from '@edx/frontend-platform';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
export async function getCourseMetadata(courseUsageKey) {
const url = `${getConfig().LMS_BASE_URL}/api/courseware/course/${courseUsageKey}`;
const { data } = await getAuthenticatedHttpClient().get(url);
const processedData = camelCaseObject(data);
return processedData;
}

View File

@@ -1,6 +0,0 @@
export { getCourseMetadata } from './api';
export {
reducer,
courseMetadataShape,
} from './slice';
export { fetchCourseMetadata } from './thunks';

View File

@@ -1,93 +0,0 @@
/* eslint-disable no-param-reassign */
import { createSlice } from '@reduxjs/toolkit';
import PropTypes from 'prop-types';
const courseMetaSlice = createSlice({
name: 'course-meta',
initialState: {
fetchState: null,
},
reducers: {
fetchCourseMetadataRequest: (draftState) => {
draftState.fetchState = 'loading';
},
fetchCourseMetadataSuccess: (draftState, { payload }) => ({
fetchState: 'loaded',
/*
* NOTE: If you change the data saved here,
* update the courseMetadataShape below!
*/
// Course identifiers
name: payload.name,
number: payload.number,
org: payload.org,
// Enrollment dates
enrollmentStart: payload.enrollmentStart,
enrollmentEnd: payload.enrollmentEnd,
// Course dates
end: payload.end,
start: payload.start,
// User access/enrollment status
enrollmentMode: payload.enrollment.mode,
isEnrolled: payload.enrollment.isActive,
userHasAccess: payload.userHasAccess,
verifiedMode: payload.verifiedMode,
// Misc
tabs: payload.tabs,
}),
fetchCourseMetadataFailure: (draftState) => {
draftState.fetchState = 'failed';
},
},
});
export const {
fetchCourseMetadataRequest,
fetchCourseMetadataSuccess,
fetchCourseMetadataFailure,
} = courseMetaSlice.actions;
export const { reducer } = courseMetaSlice;
export const courseMetadataShape = PropTypes.shape({
fetchState: PropTypes.string,
// Course identifiers
name: PropTypes.string,
number: PropTypes.string,
org: PropTypes.string,
// Enrollment dates
enrollmentStart: PropTypes.string,
enrollmentEnd: PropTypes.string,
// User access/enrollment status
enrollmentMode: PropTypes.string,
isEnrolled: PropTypes.bool,
userHasAccess: PropTypes.bool,
verifiedMode: PropTypes.shape({
price: PropTypes.number.isRequired,
currency: PropTypes.string.isRequired,
currencySymbol: PropTypes.string.isRequired,
sku: PropTypes.string.isRequired,
upgradeUrl: PropTypes.string.isRequired,
}),
// Course dates
start: PropTypes.string,
end: PropTypes.string,
// Misc
tabs: PropTypes.arrayOf(PropTypes.shape({
priority: PropTypes.number,
slug: PropTypes.string,
title: PropTypes.string,
type: PropTypes.string,
url: PropTypes.string,
})),
});

View File

@@ -1,21 +0,0 @@
/* eslint-disable import/prefer-default-export */
import {
fetchCourseMetadataRequest,
fetchCourseMetadataSuccess,
fetchCourseMetadataFailure,
} from './slice';
import {
getCourseMetadata,
} from './api';
export function fetchCourseMetadata(courseUsageKey) {
return async (dispatch) => {
dispatch(fetchCourseMetadataRequest({ courseUsageKey }));
try {
const courseMetadata = await getCourseMetadata(courseUsageKey);
dispatch(fetchCourseMetadataSuccess(courseMetadata));
} catch (error) {
dispatch(fetchCourseMetadataFailure(error));
}
};
}

View File

@@ -1,24 +0,0 @@
import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import Alert from '../user-messages/Alert';
import messages from './messages';
function EnrollmentAlert({ intl }) {
return (
<Alert type="error">
{intl.formatMessage(messages['learning.enrollment.alert'])}
{' '}
<a href={`${getConfig().LMS_BASE_URL}/api/enrollment/v1/enrollment`}>
{intl.formatMessage(messages['learning.enrollment.enroll.now'])}
</a>
</Alert>
);
}
EnrollmentAlert.propTypes = {
intl: intlShape.isRequired,
};
export default injectIntl(EnrollmentAlert);

View File

@@ -1 +0,0 @@
export { default } from './EnrollmentAlert';

View File

@@ -1,16 +0,0 @@
import { defineMessages } from '@edx/frontend-platform/i18n';
const messages = defineMessages({
'learning.enrollment.alert': {
id: 'learning.enrollment.alert',
defaultMessage: 'You must be enrolled in the course to see course content.',
description: 'Message shown to indicate that a user needs to enroll in a course prior to viewing the course content. Shown as part of an alert, along with a link to enroll.',
},
'learning.enrollment.enroll.now': {
id: 'learning.enrollment.enroll.now',
defaultMessage: 'Enroll Now',
description: 'A link prompting the user to click on it to enroll in the currently viewed course.',
},
});
export default messages;

View File

@@ -1,50 +0,0 @@
import { useContext, useState, useEffect } from 'react';
import { AppContext } from '@edx/frontend-platform/react';
import UserMessagesContext from './user-messages/UserMessagesContext';
export function useLogistrationAlert() {
const { authenticatedUser } = useContext(AppContext);
const { add, remove } = useContext(UserMessagesContext);
const [alertId, setAlertId] = useState(null);
useEffect(() => {
if (authenticatedUser === null) {
setAlertId(add({
code: 'clientLogistrationAlert',
dismissible: false,
type: 'error',
topic: 'course',
}));
} else if (alertId !== null) {
remove(alertId);
setAlertId(null);
}
return () => {
if (alertId !== null) {
remove(alertId);
}
};
}, [authenticatedUser]);
}
export function useEnrollmentAlert(isEnrolled) {
const { add, remove } = useContext(UserMessagesContext);
const [alertId, setAlertId] = useState(null);
useEffect(() => {
if (!isEnrolled) {
setAlertId(add({
code: 'clientEnrollmentAlert',
dismissible: false,
type: 'error',
topic: 'course',
}));
} else if (alertId !== null) {
remove(alertId);
setAlertId(null);
}
return () => {
if (alertId !== null) {
remove(alertId);
}
};
}, [isEnrolled]);
}

View File

@@ -1,57 +1,41 @@
import 'core-js/stable';
import 'regenerator-runtime/runtime';
import {
APP_INIT_ERROR, APP_READY, subscribe, initialize,
} from '@edx/frontend-platform';
import { APP_INIT_ERROR, APP_READY, subscribe, initialize } from '@edx/frontend-platform';
import { AppProvider, ErrorPage } from '@edx/frontend-platform/react';
import React from 'react';
import ReactDOM from 'react-dom';
import { Route, Switch, Link } from 'react-router-dom';
import { messages as headerMessages } from '@edx/frontend-component-header';
import Header, { messages as headerMessages } from '@edx/frontend-component-header';
import Footer, { messages as footerMessages } from '@edx/frontend-component-footer';
import appMessages from './i18n';
import UserMessagesProvider from './user-messages/UserMessagesProvider';
import CourseTabsNavigation from './components/CourseTabsNavigation';
import LearningSequencePage from './learning-sequence/LearningSequencePage';
import './index.scss';
import './assets/favicon.ico';
import CourseContainer from './courseware/CourseContainer';
import OutlineContainer from './outline/OutlineContainer';
import store from './store';
function courseLinks() {
// TODO: We should remove these links before we go live for learners.
return (
<main className="m-3">
<ul>
<li><Link to="/course/course-v1:edX+DemoX+Demo_Course">Visit Demo Course</Link></li>
<li><Link to="/course/course-v1:UBCx+Water201x_2+2T2015">Visit Staging Course</Link></li>
</ul>
</main>
);
}
subscribe(APP_READY, () => {
ReactDOM.render(
<AppProvider store={store}>
<UserMessagesProvider>
<Switch>
<Route exact path="/" render={courseLinks} />
<Route path="/outline/:courseUsageKey" component={OutlineContainer} />
<Route
path={[
'/course/:courseUsageKey/:sequenceId/:unitId',
'/course/:courseUsageKey/:sequenceId',
'/course/:courseUsageKey',
]}
component={CourseContainer}
/>
</Switch>
<Footer />
</UserMessagesProvider>
<AppProvider>
<Header />
<div className="container pt-2">
<CourseTabsNavigation activeTabSlug="course" />
</div>
<Switch>
{/* Staging: course-v1:UBCx+Water201x_2+2T2015 */}
<Route
exact
path="/"
render={() => <Link to="/course/course-v1%3AedX%2BDemoX%2BDemo_Course/block-v1:edX+DemoX+Demo_Course+type@sequential+block@edx_introduction/block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_0270f6de40fc">Visit Demo Course</Link>}
/>
<Route path="/course/:courseId/:subSectionId/:unitId" component={LearningSequencePage} />
<Route path="/course/:courseId/:subSectionId" component={LearningSequencePage} />
<Route path="/course/:courseId" component={LearningSequencePage} />
</Switch>
<Footer />
</AppProvider>,
document.getElementById('root'),
);

View File

@@ -1,43 +1,17 @@
$primary: #1176B2;
@import '~@edx/paragon/scss/edx/theme.scss';
@import './learning-sequence/index';
@import "~@edx/frontend-component-header/dist/index";
@import "~@edx/frontend-component-footer/dist/footer";
// TODO: Fix .btn-outline-light style in paragon
.btn-outline-light {
&:hover, &:focus {
color: $primary;
border-color: $white;
background-color: $white;
}
&:not(:disabled):not(.disabled):active {
border-color: $white;
}
}
#root {
display: flex;
flex-direction: column;
min-height: 100vh;
main {
flex-grow: 1;
}
height: 100vh;
header {
flex: 0;
.logo {
display: block;
box-sizing: content-box;
position: relative;
top: .10em;
height: 1.75rem;
margin-right: 1rem;
img {
display: block;
height: 100%;
}
}
}
footer {
@@ -45,15 +19,10 @@ $primary: #1176B2;
}
}
.course-tabs-navigation {
margin-top: 4px;
border-bottom: solid 1px #EAEAEA;
}
.nav-underline-tabs {
margin: 0;
.nav-link {
border-bottom: 4px solid transparent;
color: theme-color('gray', 400);
color: theme-color('gray', 700);
&:hover,
&:focus,
@@ -64,109 +33,3 @@ $primary: #1176B2;
}
}
}
.course-content-container {
border: solid 1px #EAEAEA;
border-radius: 4px;
margin-bottom: 4rem;
display: flex;
flex-direction: column;
flex-grow: 1;
}
.sequence-navigation {
display: flex;
margin: -1px -1px 0;
.btn {
flex-grow: 1;
display: block;
border-radius: 0;
border: solid 1px #EAEAEA;
margin-left: -1px;
position: relative;
font-weight: 400;
flex-basis: 80%;
padding: .5rem;
color: theme-color('gray', 400);
&:hover,
&:focus,
&.active {
color: theme-color('gray', 700);
}
&:focus {
z-index: 1;
}
&.active {
&:after {
content: '';
position: absolute;
bottom: -1px;
left: 0;
right: 0;
height: 2px;
background: $primary;
}
}
&.complete {
background-color: #EEF7E5;
color: $success;
}
&:first-child {
margin-left: 0;
}
}
.previous-btn, .next-btn {
flex-basis: 10em;
min-width: 9em;
color: theme-color('gray', 700);
display: inline-flex;
justify-content: center;
align-items: center;
}
.previous-btn {
border-top-left-radius: 4px;
}
.next-btn {
border-top-right-radius: 4px;
}
}
.unit-content-container {
padding-left: 20px;
padding-right: 20px;
max-width: 1024px;
margin-left: auto;
margin-right: auto;
width: 100%;
@media (min-width: 830px) {
padding-left: 40px;
padding-right: 40px;
}
}
.below-unit-navigation {
display: flex;
justify-content: center;
margin-top: 2rem;
margin-bottom: 2rem;
padding-left: 6rem;
padding-right: 6rem;
.previous-button,
.next-button {
border-radius: 4px;
&:focus:before {
border-radius: 6px;
}
}
}
#unit-iframe {
max-width: 1024px;
width: 100%;
margin: 0 auto;
border: none;
display: block;
}

View File

@@ -0,0 +1,54 @@
import React, { useContext } from 'react';
import PropTypes from 'prop-types';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faChevronRight } from '@fortawesome/free-solid-svg-icons';
import { getConfig } from '@edx/frontend-platform';
import CourseStructureContext from './CourseStructureContext';
import { useBlockAncestry } from './data/hooks';
const CourseBreadcrumbs = () => {
const { courseId, unitId } = useContext(CourseStructureContext);
const ancestry = useBlockAncestry(unitId);
const links = ancestry.map(ancestor => ({
id: ancestor.id,
label: ancestor.displayName,
url: `${getConfig().LMS_BASE_URL}/courses/${courseId}/course/#${ancestor.id}`,
}));
return (
<nav aria-label="breadcrumb">
<ol className="list-inline">
{links.map(({ id, url, label }, i) => (
<CourseBreadcrumb key={id} url={url} label={label} last={i === links.length - 1} />
))}
</ol>
</nav>
);
};
export default CourseBreadcrumbs;
function CourseBreadcrumb({ url, label, last }) {
return (
<React.Fragment key={`${label}-${url}`}>
<li className="list-inline-item">
{last ? label : (<a href={url}>{label}</a>)}
</li>
{!last &&
<li className="list-inline-item" role="presentation" aria-label="spacer">
<FontAwesomeIcon icon={faChevronRight} />
</li>
}
</React.Fragment>
);
}
CourseBreadcrumb.propTypes = {
url: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
last: PropTypes.bool.isRequired,
};

View File

@@ -0,0 +1,5 @@
import React from 'react';
const CourseStructureContext = React.createContext({});
export default CourseStructureContext;

View File

@@ -0,0 +1,215 @@
import React, { useEffect } from 'react';
import PropTypes from 'prop-types';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import PageLoading from './PageLoading';
import messages from './messages';
import CourseBreadcrumbs from './CourseBreadcrumbs';
import CourseStructureContext from './CourseStructureContext';
import { useLoadCourseStructure, useMissingSubSectionRedirect } from './data/hooks';
import SubSection from './sub-section/SubSection';
import { history } from '@edx/frontend-platform';
import Sequence from './sequence/Sequence';
function LearningSequencePage({ match, intl }) {
const {
courseId,
subSectionId,
unitId,
} = match.params;
const { blocks, loaded, courseBlockId } = useLoadCourseStructure(courseId);
useMissingSubSectionRedirect(loaded, blocks, courseId, courseBlockId, subSectionId);
return (
<main className="container-fluid d-flex flex-column flex-grow-1">
<CourseStructureContext.Provider value={{
courseId,
courseBlockId,
subSectionId,
unitId,
blocks,
loaded,
}}
>
{!loaded && <PageLoading
srMessage={intl.formatMessage(messages['learn.loading.learning.sequence'])}
/>}
{loaded && unitId && <CourseBreadcrumbs />}
{subSectionId && (
<Sequence
courseId={courseId}
id={subSectionId}
unitIds={[
"block-v1:edX+DemoX+Demo_Course+type@vertical+block@867dddb6f55d410caaa9c1eb9c6743ec",
"block-v1:edX+DemoX+Demo_Course+type@vertical+block@3e3f9b5199ba4e96b2fc6539087cfe2c",
"block-v1:edX+DemoX+Demo_Course+type@vertical+block@4f6c1b4e316a419ab5b6bf30e6c708e9",
"block-v1:edX+DemoX+Demo_Course+type@vertical+block@3dc16db8d14842e38324e95d4030b8a0",
"block-v1:edX+DemoX+Demo_Course+type@vertical+block@4a1bba2a403f40bca5ec245e945b0d76",
"block-v1:edX+DemoX+Demo_Course+type@vertical+block@f0e6d90842c44cc7a50fd1a18a7dd982",
"block-v1:edX+DemoX+Demo_Course+type@vertical+block@256f17a44983429fb1a60802203ee4e0",
"block-v1:edX+DemoX+Demo_Course+type@vertical+block@e3601c0abee6427d8c17e6d6f8fdddd1",
"block-v1:edX+DemoX+Demo_Course+type@vertical+block@a79d59cd72034188a71d388f4954a606",
"block-v1:edX+DemoX+Demo_Course+type@vertical+block@134df56c516a4a0dbb24dd5facef746e",
"block-v1:edX+DemoX+Demo_Course+type@vertical+block@d91b9e5d8bc64d57a1332d06bf2f2193",
]}
units={{
"block-v1:edX+DemoX+Demo_Course+type@vertical+block@867dddb6f55d410caaa9c1eb9c6743ec": {
"type": "other",
"path": "Example Week 1: Getting Started > Lesson 1 - Getting Started > Getting Started",
"bookmarked": false,
"graded": false,
"page_title": "Getting Started",
"href": "",
"complete": true,
"content": "",
"id": "block-v1:edX+DemoX+Demo_Course+type@vertical+block@867dddb6f55d410caaa9c1eb9c6743ec"
},
"block-v1:edX+DemoX+Demo_Course+type@vertical+block@3e3f9b5199ba4e96b2fc6539087cfe2c": {
"type": "other",
"path": "Example Week 1: Getting Started > Lesson 1 - Getting Started > MY unit",
"bookmarked": false,
"graded": false,
"page_title": "MY unit",
"href": "",
"complete": false,
"content": "",
"id": "block-v1:edX+DemoX+Demo_Course+type@vertical+block@3e3f9b5199ba4e96b2fc6539087cfe2c"
},
"block-v1:edX+DemoX+Demo_Course+type@vertical+block@4f6c1b4e316a419ab5b6bf30e6c708e9": {
"type": "video",
"path": "Example Week 1: Getting Started > Lesson 1 - Getting Started > Working with Videos",
"bookmarked": false,
"graded": false,
"page_title": "Working with Videos",
"href": "",
"complete": false,
"content": "",
"id": "block-v1:edX+DemoX+Demo_Course+type@vertical+block@4f6c1b4e316a419ab5b6bf30e6c708e9"
},
"block-v1:edX+DemoX+Demo_Course+type@vertical+block@3dc16db8d14842e38324e95d4030b8a0": {
"type": "video",
"path": "Example Week 1: Getting Started > Lesson 1 - Getting Started > Videos on edX",
"bookmarked": false,
"graded": false,
"page_title": "Videos on edX",
"href": "",
"complete": false,
"content": "",
"id": "block-v1:edX+DemoX+Demo_Course+type@vertical+block@3dc16db8d14842e38324e95d4030b8a0"
},
"block-v1:edX+DemoX+Demo_Course+type@vertical+block@4a1bba2a403f40bca5ec245e945b0d76": {
"type": "other",
"path": "Example Week 1: Getting Started > Lesson 1 - Getting Started > Video Demonstrations",
"bookmarked": false,
"graded": false,
"page_title": "Video Demonstrations",
"href": "",
"complete": false,
"content": "",
"id": "block-v1:edX+DemoX+Demo_Course+type@vertical+block@4a1bba2a403f40bca5ec245e945b0d76"
},
"block-v1:edX+DemoX+Demo_Course+type@vertical+block@f0e6d90842c44cc7a50fd1a18a7dd982": {
"type": "video",
"path": "Example Week 1: Getting Started > Lesson 1 - Getting Started > Video Demonstrations",
"bookmarked": false,
"graded": false,
"page_title": "Video Demonstrations",
"href": "",
"complete": false,
"content": "",
"id": "block-v1:edX+DemoX+Demo_Course+type@vertical+block@f0e6d90842c44cc7a50fd1a18a7dd982"
},
"block-v1:edX+DemoX+Demo_Course+type@vertical+block@256f17a44983429fb1a60802203ee4e0": {
"type": "video",
"path": "Example Week 1: Getting Started > Lesson 1 - Getting Started > Video Presentation Styles",
"bookmarked": false,
"graded": false,
"page_title": "Video Presentation Styles",
"href": "",
"complete": false,
"content": "",
"id": "block-v1:edX+DemoX+Demo_Course+type@vertical+block@256f17a44983429fb1a60802203ee4e0"
},
"block-v1:edX+DemoX+Demo_Course+type@vertical+block@e3601c0abee6427d8c17e6d6f8fdddd1": {
"type": "problem",
"path": "Example Week 1: Getting Started > Lesson 1 - Getting Started > Interactive Questions",
"bookmarked": false,
"graded": false,
"page_title": "Interactive Questions",
"href": "",
"complete": false,
"content": "",
"id": "block-v1:edX+DemoX+Demo_Course+type@vertical+block@e3601c0abee6427d8c17e6d6f8fdddd1"
},
"block-v1:edX+DemoX+Demo_Course+type@vertical+block@a79d59cd72034188a71d388f4954a606": {
"type": "other",
"path": "Example Week 1: Getting Started > Lesson 1 - Getting Started > Exciting Labs and Tools",
"bookmarked": false,
"graded": false,
"page_title": "Exciting Labs and Tools",
"href": "",
"complete": false,
"content": "",
"id": "block-v1:edX+DemoX+Demo_Course+type@vertical+block@a79d59cd72034188a71d388f4954a606"
},
"block-v1:edX+DemoX+Demo_Course+type@vertical+block@134df56c516a4a0dbb24dd5facef746e": {
"type": "problem",
"path": "Example Week 1: Getting Started > Lesson 1 - Getting Started > Reading Assignments",
"bookmarked": false,
"graded": false,
"page_title": "Reading Assignments",
"href": "",
"complete": false,
"content": "",
"id": "block-v1:edX+DemoX+Demo_Course+type@vertical+block@134df56c516a4a0dbb24dd5facef746e"
},
"block-v1:edX+DemoX+Demo_Course+type@vertical+block@d91b9e5d8bc64d57a1332d06bf2f2193": {
"type": "other",
"path": "Example Week 1: Getting Started > Lesson 1 - Getting Started > When Are Your Exams? ",
"bookmarked": false,
"graded": false,
"page_title": "When Are Your Exams? ",
"href": "",
"complete": false,
"content": "",
"id": "block-v1:edX+DemoX+Demo_Course+type@vertical+block@d91b9e5d8bc64d57a1332d06bf2f2193"
},
}}
displayName="Sequence Name"
activeUnitId="block-v1:edX+DemoX+Demo_Course+type@vertical+block@867dddb6f55d410caaa9c1eb9c6743ec"
showCompletion={true}
isTimeLimited={false}
bannerText={null}
onNext={() => {}}
onPrevious={() => {}}
onNavigateUnit={() => {}}
isGated={false}
prerequisite={{
name: 'Prerequisite name',
url: 'url? or id',
id: 'asdasd',
}}
savePosition={true}
/>
)}
</CourseStructureContext.Provider>
</main>
);
}
export default injectIntl(LearningSequencePage);
LearningSequencePage.propTypes = {
match: PropTypes.shape({
params: PropTypes.shape({
courseId: PropTypes.string.isRequired,
subSectionId: PropTypes.string,
unitId: PropTypes.string,
}).isRequired,
}).isRequired,
intl: intlShape.isRequired,
};

View File

@@ -0,0 +1,15 @@
/* eslint-disable import/prefer-default-export */
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import { getConfig } from '@edx/frontend-platform';
export async function getCourseBlocks(courseId, username) {
const url = new URL(`${getConfig().LMS_BASE_URL}/api/courses/v2/blocks/`);
url.searchParams.append('course_id', decodeURIComponent(courseId));
url.searchParams.append('username', username);
url.searchParams.append('depth', 3);
url.searchParams.append('requested_fields', 'children,show_gated_sections');
const { data } = await getAuthenticatedHttpClient().get(url.href, {});
return data;
}

View File

@@ -0,0 +1,136 @@
import { useContext, useMemo, useState, useEffect } from 'react';
import { history } from '@edx/frontend-platform';
import { AppContext } from '@edx/frontend-platform/react';
import CourseStructureContext from '../CourseStructureContext';
import { getCourseBlocks } from './api';
import { findBlockAncestry, createBlocksMap, createSubSectionIdList, createUnitIdList } from './utils';
export function useBlockAncestry(blockId) {
const { blocks, loaded } = useContext(CourseStructureContext);
return useMemo(() => {
if (!loaded) {
return [];
}
return findBlockAncestry(
blocks,
blockId,
);
}, [blocks, blockId, loaded]);
}
export function useMissingSubSectionRedirect(
loaded,
blocks,
courseId,
courseBlockId,
subSectionId,
) {
useEffect(() => {
if (loaded && !subSectionId) {
const course = blocks[courseBlockId];
const nextSectionId = course.children[0];
const nextSection = blocks[nextSectionId];
const nextSubSectionId = nextSection.children[0];
const nextSubSection = blocks[nextSubSectionId];
const nextUnitId = nextSubSection.children[0];
history.push(`/course/${courseId}/${nextSubSectionId}/${nextUnitId}`);
}
}, [loaded, subSectionId]);
}
export function useLoadCourseStructure(courseId) {
const { authenticatedUser } = useContext(AppContext);
const [blocks, setBlocks] = useState(null);
const [loaded, setLoaded] = useState(false);
const [courseBlockId, setCourseBlockId] = useState();
useEffect(() => {
setLoaded(false);
getCourseBlocks(courseId, authenticatedUser.username).then((blocksData) => {
setBlocks(createBlocksMap(blocksData.blocks));
setCourseBlockId(blocksData.root);
setLoaded(true);
});
}, [courseId]);
return {
blocks, loaded, courseBlockId,
};
}
export function useCurrentCourse() {
const { loaded, courseBlockId, blocks } = useContext(CourseStructureContext);
return loaded ? blocks[courseBlockId] : null;
}
export function useCurrentSubSection() {
const { loaded, blocks, subSectionId } = useContext(CourseStructureContext);
return loaded && subSectionId ? blocks[subSectionId] : null;
}
export function useCurrentSection() {
const { loaded, blocks } = useContext(CourseStructureContext);
const subSection = useCurrentSubSection();
return loaded ? blocks[subSection.parentId] : null;
}
export function useCurrentUnit() {
const { loaded, blocks, unitId } = useContext(CourseStructureContext);
return loaded && unitId ? blocks[unitId] : null;
}
export function useUnitIds() {
const { loaded, blocks, courseBlockId } = useContext(CourseStructureContext);
return useMemo(
() => (loaded ? createUnitIdList(blocks, courseBlockId) : []),
[loaded, blocks, courseBlockId],
);
}
export function usePreviousUnit() {
const { loaded, blocks, unitId } = useContext(CourseStructureContext);
const unitIds = useUnitIds();
const currentUnitIndex = unitIds.indexOf(unitId);
if (currentUnitIndex === 0) {
return null;
}
return loaded ? blocks[unitIds[currentUnitIndex - 1]] : null;
}
export function useNextUnit() {
const { loaded, blocks, unitId } = useContext(CourseStructureContext);
const unitIds = useUnitIds();
const currentUnitIndex = unitIds.indexOf(unitId);
if (currentUnitIndex === unitIds.length - 1) {
return null;
}
return loaded ? blocks[unitIds[currentUnitIndex + 1]] : null;
}
export function useCurrentSubSectionUnits() {
const { loaded, blocks } = useContext(CourseStructureContext);
const subSection = useCurrentSubSection();
return loaded ? subSection.children.map(id => blocks[id]) : [];
}
export function useSubSectionIdList() {
const { loaded, blocks, courseBlockId } = useContext(CourseStructureContext);
const subSectionIdList = useMemo(
() => (loaded ? createSubSectionIdList(blocks, courseBlockId) : []),
[blocks, courseBlockId],
);
return subSectionIdList;
}

View File

@@ -29,18 +29,18 @@ export function createBlocksMap(blocksData) {
return blocks;
}
export function createSequenceIdList(blocks, entryPointId, sequences = []) {
export function createSubSectionIdList(blocks, entryPointId, subSections = []) {
const block = blocks[entryPointId];
if (block.type === 'sequential') {
sequences.push(block.id);
subSections.push(block.id);
}
if (Array.isArray(block.children)) {
for (let i = 0; i < block.children.length; i++) {
const childId = block.children[i];
createSequenceIdList(blocks, childId, sequences);
createSubSectionIdList(blocks, childId, subSections);
}
}
return sequences;
return subSections;
}
export function createUnitIdList(blocks, entryPointId, units = []) {

View File

@@ -0,0 +1,4 @@
iframe {
border: 0;
width: 100%;
}

View File

@@ -1,7 +1,7 @@
import React from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faCheck } from '@fortawesome/free-solid-svg-icons';
import { faCheckCircle } from '@fortawesome/free-solid-svg-icons';
export default function CompleteIcon(props) {
return <FontAwesomeIcon icon={faCheck} {...props} />;
return <FontAwesomeIcon icon={faCheckCircle} {...props} />
}

View File

@@ -0,0 +1,139 @@
import React, { useState, useEffect, Suspense } from 'react';
import PropTypes from 'prop-types';
import Unit from './Unit';
import SequenceNavigation from './SequenceNavigation';
import PageLoading from '../PageLoading';
import { getBlockCompletion, saveSequencePosition } from './api';
const ContentLock = React.lazy(() => import('./content-lock'));
import messages from './messages';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
function Sequence({
courseId,
id,
unitIds,
units: initialUnits,
displayName,
showCompletion,
isTimeLimited,
bannerText,
onNext,
onPrevious,
onNavigateUnit,
isGated,
prerequisite,
savePosition,
activeUnitId: initialActiveUnitId,
intl,
}) {
const [units, setUnits] = useState(initialUnits);
const [activeUnitId, setActiveUnitId] = useState(initialActiveUnitId);
const activeUnitIndex = unitIds.indexOf(activeUnitId);
const activeUnit = units[activeUnitId];
const unitsArr = unitIds.map((unitId) => ({
...units[unitId],
id: unitId,
isActive: unitId === activeUnitId,
}));
const updateUnitCompletion = (unitId) => {
// If the unit is already complete, don't check.
if (units[unitId].complete) {
return;
}
getBlockCompletion(courseId, id, unitId).then((isComplete) => {
if (isComplete) {
setUnits({
...units,
[unitId]: { ...units[unitId], complete: isComplete },
});
}
})
};
const handleNext = () => {
if (activeUnitIndex < unitIds.length - 1) {
handleNavigate(activeUnitIndex + 1);
} else {
onNext();
}
};
const handlePrevious = () => {
if (activeUnitIndex > 0) {
handleNavigate(activeUnitIndex - 1);
} else {
onPrevious();
}
};
const handleNavigate = (unitIndex) => {
const newUnitId = unitIds[unitIndex];
if (showCompletion) {
updateUnitCompletion(activeUnitId);
}
setActiveUnitId(newUnitId);
onNavigateUnit(newUnitId, units[newUnitId]);
};
useEffect(() => {
if (savePosition) {
saveSequencePosition(courseId, id, activeUnitIndex);
}
}, [activeUnitId]);
return (
<div className="d-flex flex-column flex-grow-1">
<SequenceNavigation
onNext={handleNext}
onNavigate={handleNavigate}
onPrevious={handlePrevious}
units={unitsArr}
isLocked={isGated}
showCompletion={showCompletion}
/>
{isGated? (
<Suspense fallback={<PageLoading
srMessage={intl.formatMessage(messages['learn.loading.content.lock'])}
/>}>
<ContentLock
courseId={courseId}
sectionName={displayName}
prereqSectionName={prerequisite.name}
prereqId={prerequisite.id}
/>
</Suspense>
): (
<Unit key={activeUnitId} {...activeUnit} />
)}
</div>
);
}
Sequence.propTypes = {
id: PropTypes.string.isRequired,
courseId: PropTypes.string.isRequired,
unitIds: PropTypes.arrayOf(PropTypes.string).isRequired,
units: PropTypes.objectOf(PropTypes.shape({
})),
displayName: PropTypes.string.isRequired,
activeUnitId: PropTypes.string.isRequired,
showCompletion: PropTypes.bool.isRequired,
isTimeLimited: PropTypes.bool.isRequired,
bannerText: PropTypes.string,
onNext: PropTypes.func.isRequired,
onPrevious: PropTypes.func.isRequired,
onNavigateUnit: PropTypes.func.isRequired,
isGated: PropTypes.bool.isRequired,
prerequisite: PropTypes.shape({
name: PropTypes.string.isRequired,
url: PropTypes.string.isRequired,
id: PropTypes.string.isRequired,
}),
savePosition: PropTypes.bool.isRequired,
intl: intlShape.isRequired,
};
export default injectIntl(Sequence);

View File

@@ -0,0 +1,35 @@
import React from 'react';
import { Button } from '@edx/paragon';
import UnitButton from './UnitButton';
export default function SequenceNavigation({
onNext,
onPrevious,
onNavigate,
units,
isLocked,
showCompletion,
}) {
const unitButtons = units.map((unit, index) => (
<UnitButton
key={unit.id}
{...unit}
isComplete={showCompletion && unit.complete}
onClick={onNavigate.bind(null, index)}
/>
));
return (
<nav className="flex-grow-0 d-flex w-100 mb-3 btn-group">
<Button className="btn-outline-primary" onClick={onPrevious}>
Previous
</Button>
{isLocked ? <UnitButton type="lock" isActive={true} /> : unitButtons}
<Button className="btn-outline-primary" onClick={onNext}>
Next
</Button>
</nav>
);
}

View File

@@ -0,0 +1,22 @@
import React, { useRef } from 'react';
import PropTypes from 'prop-types';
import { getConfig } from '@edx/frontend-platform';
export default function Unit({ id, title }) {
const iframeRef = useRef(null);
const iframeUrl = `${getConfig().LMS_BASE_URL}/xblock/${id}`;
return (
<iframe
className="flex-grow-1"
title={title}
ref={iframeRef}
src={iframeUrl}
/>
);
}
Unit.propTypes = {
id: PropTypes.string.isRequired,
title: PropTypes.string.isRequired,
};

View File

@@ -0,0 +1,29 @@
import React from 'react';
import classNames from 'classnames';
import { Button } from '@edx/paragon';
import UnitIcon from './UnitIcon';
import CompleteIcon from './CompleteIcon';
export default function UnitButton({
onClick,
title,
type,
isActive,
isComplete,
}) {
return (
<Button
className={classNames({
active: isActive,
"btn-outline-primary": !isActive,
"btn-outline-secondary": isActive,
})}
disabled={isActive}
onClick={onClick}
title={title}
>
<UnitIcon type={type} />
{isComplete ? <CompleteIcon className="text-success ml-2" /> : null}
</Button>
)
}

View File

@@ -1,9 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import {
faFilm, faBook, faEdit, faTasks, faLock,
} from '@fortawesome/free-solid-svg-icons';
import { faFilm, faBook, faPencilAlt, faTasks, faLock } from '@fortawesome/free-solid-svg-icons';
export default function UnitIcon({ type }) {
let icon = null;
@@ -18,7 +16,7 @@ export default function UnitIcon({ type }) {
icon = faTasks;
break;
case 'problem':
icon = faEdit;
icon = faPencilAlt;
break;
case 'lock':
icon = faLock;

View File

@@ -0,0 +1,50 @@
import { getConfig } from '@edx/frontend-platform';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
/* eslint-disable import/prefer-default-export */
const getSequenceXModuleHandlerUrl = (courseId, sequenceId) =>
`${getConfig().LMS_BASE_URL}/courses/${courseId}/xblock/${sequenceId}/handler/xmodule_handler`;
export async function saveSequencePosition(courseId, sequenceId, position) {
// Post data sent to this endpoint must be url encoded
// TODO: Remove the need for this to be the case.
// TODO: Ensure this usage of URLSearchParams is working in Internet Explorer
const urlEncoded = new URLSearchParams();
urlEncoded.append('position', position + 1);
const requestConfig = {
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
};
const { data } = await getAuthenticatedHttpClient().post(
`${getSequenceXModuleHandlerUrl(courseId, sequenceId)}/goto_position`,
urlEncoded.toString(),
requestConfig,
);
return data;
}
export async function getBlockCompletion(courseId, sequenceId, usageKey) {
// Post data sent to this endpoint must be url encoded
// TODO: Remove the need for this to be the case.
// TODO: Ensure this usage of URLSearchParams is working in Internet Explorer
const urlEncoded = new URLSearchParams();
urlEncoded.append('usage_key', usageKey);
const requestConfig = {
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
};
const { data } = await getAuthenticatedHttpClient().post(
`${getSequenceXModuleHandlerUrl(courseId, sequenceId)}/get_completion`,
urlEncoded.toString(),
requestConfig,
);
if (data.complete) {
return true;
}
return false;
}

View File

@@ -1,5 +1,4 @@
import React, { useCallback } from 'react';
import PropTypes from 'prop-types';
import React, { useContext, useCallback } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faLock } from '@fortawesome/free-solid-svg-icons';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
@@ -8,25 +7,21 @@ import { Button } from '@edx/paragon';
import messages from './messages';
function ContentLock({
intl, courseUsageKey, prereqSectionName, prereqId, sectionName,
}) {
function ContentLock({ intl, courseId, prereqSectionName, prereqId, sectionName }) {
const handleClick = useCallback(() => {
history.push(`/course/${courseUsageKey}/${prereqId}`);
history.push(`/course/${courseId}/${prereqId}`);
});
return (
<>
<h3>
<FontAwesomeIcon icon={faLock} />
{' '}
<FontAwesomeIcon icon={faLock} />{' '}
{sectionName}
</h3>
<h4>{intl.formatMessage(messages['learn.contentLock.content.locked'])}</h4>
<p>
{intl.formatMessage(messages['learn.contentLock.complete.prerequisite'], {
prereqSectionName,
})}
<p>{intl.formatMessage(messages['learn.contentLock.complete.prerequisite'], {
prereqSectionName,
})}
</p>
<p>
<Button className="btn-primary" onClick={handleClick}>{intl.formatMessage(messages['learn.contentLock.goToSection'])}</Button>
@@ -34,11 +29,9 @@ function ContentLock({
</>
);
}
ContentLock.propTypes = {
intl: intlShape.isRequired,
courseUsageKey: PropTypes.string.isRequired,
prereqSectionName: PropTypes.string.isRequired,
prereqId: PropTypes.string.isRequired,
sectionName: PropTypes.string.isRequired,
};
export default injectIntl(ContentLock);

View File

@@ -0,0 +1,65 @@
import React, { useContext, Suspense } from 'react';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import SubSectionNavigation from './SubSectionNavigation';
import CourseStructureContext from '../CourseStructureContext';
import Unit from './Unit';
import {
useLoadSubSectionMetadata,
useExamRedirect,
usePersistentUnitPosition,
useMissingUnitRedirect,
} from './data/hooks';
import SubSectionMetadataContext from './SubSectionMetadataContext';
import PageLoading from '../PageLoading';
import messages from './messages';
import { useCurrentUnit } from '../data/hooks';
const ContentLock = React.lazy(() => import('./content-lock'));
function SubSection({ intl }) {
const {
courseId,
subSectionId,
unitId,
blocks,
} = useContext(CourseStructureContext);
const { metadata, loaded } = useLoadSubSectionMetadata(courseId, subSectionId);
usePersistentUnitPosition(courseId, subSectionId, unitId, metadata);
useExamRedirect(metadata, blocks);
useMissingUnitRedirect(metadata, loaded);
const unit = useCurrentUnit();
const ready = blocks !== null && metadata !== null && unitId && unit;
if (!ready) {
return null;
}
const isGated = metadata.gatedContent.gated;
return (
<SubSectionMetadataContext.Provider value={metadata}>
<section className="d-flex flex-column flex-grow-1">
<SubSectionNavigation />
{isGated && (
<Suspense fallback={<PageLoading
srMessage={intl.formatMessage(messages['learn.loading.content.lock'])}
/>}
>
<ContentLock />
</Suspense>
)}
{!isGated && <Unit id={unitId} unit={unit} />}
</section>
</SubSectionMetadataContext.Provider>
);
}
SubSection.propTypes = {
intl: intlShape.isRequired,
};
export default injectIntl(SubSection);

View File

@@ -0,0 +1,5 @@
import React from 'react';
const SubSectionMetadataContext = React.createContext({});
export default SubSectionMetadataContext;

View File

@@ -0,0 +1,144 @@
import React, { useCallback, useContext } from 'react';
import PropTypes from 'prop-types';
import { history } from '@edx/frontend-platform';
import { Button } from '@edx/paragon';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faFilm, faBook, faPencilAlt, faTasks, faLock } from '@fortawesome/free-solid-svg-icons';
import { usePreviousUnit, useNextUnit, useCurrentSubSectionUnits, useCurrentUnit } from '../data/hooks';
import CourseStructureContext from '../CourseStructureContext';
import SubSectionMetadataContext from './SubSectionMetadataContext';
function UnitIcon({ type }) {
let icon = null;
switch (type) {
case 'video':
icon = faFilm;
break;
case 'other':
icon = faBook;
break;
case 'vertical':
icon = faTasks;
break;
case 'problem':
icon = faPencilAlt;
break;
case 'lock':
icon = faLock;
break;
default:
icon = faBook;
}
return (
<FontAwesomeIcon icon={icon} />
);
}
UnitIcon.propTypes = {
type: PropTypes.oneOf(['video', 'other', 'vertical', 'problem', 'lock']).isRequired,
};
export default function SubSectionNavigation() {
const { courseId, unitId } = useContext(CourseStructureContext);
const previousUnit = usePreviousUnit();
const nextUnit = useNextUnit();
const handlePreviousClick = useCallback(() => {
if (previousUnit) {
history.push(`/course/${courseId}/${previousUnit.parentId}/${previousUnit.id}`);
}
});
const handleNextClick = useCallback(() => {
if (nextUnit) {
history.push(`/course/${courseId}/${nextUnit.parentId}/${nextUnit.id}`);
}
});
const handleUnitClick = useCallback((unit) => {
history.push(`/course/${courseId}/${unit.parentId}/${unit.id}`);
});
if (!unitId) {
return null;
}
return (
<nav className="flex-grow-0 d-flex w-100 mb-3">
<Button
key="previous"
className="btn-outline-primary"
onClick={handlePreviousClick}
>
Previous
</Button>
<UnitNavigation clickHandler={handleUnitClick} />
<Button
key="next"
className="btn-outline-primary"
onClick={handleNextClick}
>
Next
</Button>
</nav>
);
}
function UnitNavigation({ clickHandler }) {
const currentUnit = useCurrentUnit();
const units = useCurrentSubSectionUnits();
const metadata = useContext(SubSectionMetadataContext);
const isGated = metadata.gatedContent.gated;
return (
<div className="btn-group ml-2 mr-2 flex-grow-1 d-flex" role="group">
{!isGated && units.map(unit => (
<UnitButton key={unit.id} unit={unit} disabled={unit.id === currentUnit.id} clickHandler={clickHandler} />
))}
{isGated && <UnitButton key={currentUnit.id} unit={currentUnit} disabled locked />}
</div>
);
}
UnitNavigation.propTypes = {
clickHandler: PropTypes.func.isRequired,
};
function UnitButton({
unit, disabled, locked, clickHandler,
}) {
const { id, type } = unit;
const handleClick = useCallback(() => {
if (clickHandler !== null) {
clickHandler(unit);
}
}, [unit]);
return (
<Button
key={id}
className="btn-outline-secondary unit-button flex-grow-1"
onClick={handleClick}
disabled={disabled}
>
<UnitIcon type={locked ? 'lock' : type} />
</Button>
);
}
UnitButton.propTypes = {
unit: PropTypes.shape({
id: PropTypes.string.isRequired,
type: PropTypes.oneOf(['video', 'other', 'vertical', 'problem']).isRequired,
}).isRequired,
disabled: PropTypes.bool.isRequired, // Whether or not the button will function.
locked: PropTypes.bool, // Whether the unit is semantically "locked" and unnavigable.
clickHandler: PropTypes.func,
};
UnitButton.defaultProps = {
clickHandler: null,
locked: false,
};

View File

@@ -0,0 +1,24 @@
import React, { useRef } from 'react';
import PropTypes from 'prop-types';
import { getConfig } from '@edx/frontend-platform';
export default function Unit({ id, unit }) {
const iframeRef = useRef(null);
const iframeUrl = `${getConfig().LMS_BASE_URL}/xblock/${id}`;
const { displayName } = unit;
return (
<iframe
className="flex-grow-1"
title={displayName}
ref={iframeRef}
src={iframeUrl}
/>
);
}
Unit.propTypes = {
id: PropTypes.string.isRequired,
unit: PropTypes.shape({
displayName: PropTypes.string.isRequired,
}).isRequired,
};

View File

@@ -0,0 +1,44 @@
import React, { useContext, useCallback } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faLock } from '@fortawesome/free-solid-svg-icons';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { history } from '@edx/frontend-platform';
import { Button } from '@edx/paragon';
import SubSectionMetadataContext from '../SubSectionMetadataContext';
import messages from './messages';
import { useCurrentSubSection } from '../../data/hooks';
import CourseStructureContext from '../../CourseStructureContext';
function ContentLock({ intl }) {
const { courseId } = useContext(CourseStructureContext);
const metadata = useContext(SubSectionMetadataContext);
const subSection = useCurrentSubSection();
const handleClick = useCallback(() => {
history.push(`/course/${courseId}/${metadata.gatedContent.prereqId}`);
});
return (
<>
<h3>
<FontAwesomeIcon icon={faLock} />{' '}
{subSection.displayName}
</h3>
<h4>{intl.formatMessage(messages['learn.contentLock.content.locked'])}</h4>
<p>{intl.formatMessage(messages['learn.contentLock.complete.prerequisite'], {
prereqSectionName: metadata.gatedContent.prereqSectionName,
})}
</p>
<p>
<Button className="btn-primary" onClick={handleClick}>{intl.formatMessage(messages['learn.contentLock.goToSection'])}</Button>
</p>
</>
);
}
ContentLock.propTypes = {
intl: intlShape.isRequired,
};
export default injectIntl(ContentLock);

View File

@@ -0,0 +1 @@
export { default } from './ContentLock';

View File

@@ -0,0 +1,21 @@
import { defineMessages } from '@edx/frontend-platform/i18n';
const messages = defineMessages({
'learn.contentLock.content.locked': {
id: 'learn.contentLock.content.locked',
defaultMessage: 'Content Locked',
description: 'Message shown to indicate that a piece of content is unavailable and has a prerequisite.',
},
'learn.contentLock.complete.prerequisite': {
id: 'learn.contentLock.complete.prerequisite',
defaultMessage: "You must complete the prerequisite: '{prereqSectionName}' to access this content.",
description: 'Message shown to indicate which prerequisite the student must complete prior to accessing the locked content. {prereqSectionName} is the name of the prerequisite.',
},
'learn.contentLock.goToSection': {
id: 'learn.contentLock.goToSection',
defaultMessage: 'Go To Prerequisite Section',
description: 'A button users can click that navigates their browser to the prerequisite of this section.',
},
});
export default messages;

View File

@@ -0,0 +1,33 @@
import { getConfig } from '@edx/frontend-platform';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
/* eslint-disable import/prefer-default-export */
const getSubSectionXModuleHandlerUrl = (courseId, subSectionId) =>
`${getConfig().LMS_BASE_URL}/courses/${courseId}/xblock/${subSectionId}/handler/xmodule_handler`;
export async function getSubSectionMetadata(courseId, subSectionId) {
const { data } = await getAuthenticatedHttpClient()
.get(`${getSubSectionXModuleHandlerUrl(courseId, subSectionId)}/metadata`, {});
return data;
}
export async function saveSubSectionPosition(courseId, subSectionId, position) {
// Post data sent to this endpoint must be url encoded
// TODO: Remove the need for this to be the case.
// TODO: Ensure this usage of URLSearchParams is working in Internet Explorer
const urlEncoded = new URLSearchParams();
urlEncoded.append('position', position);
const requestConfig = {
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
};
const { data } = await getAuthenticatedHttpClient().post(
`${getSubSectionXModuleHandlerUrl(courseId, subSectionId)}/goto_position`,
urlEncoded.toString(),
requestConfig,
);
return data;
}

View File

@@ -0,0 +1,75 @@
import { useState, useEffect, useContext } from 'react';
import { camelCaseObject, history } from '@edx/frontend-platform';
import { getSubSectionMetadata, saveSubSectionPosition } from './api';
import CourseStructureContext from '../../CourseStructureContext';
export function useLoadSubSectionMetadata(courseId, subSectionId) {
const [metadata, setMetadata] = useState(null);
const [loaded, setLoaded] = useState(false);
useEffect(() => {
setLoaded(false);
setMetadata(null);
getSubSectionMetadata(courseId, subSectionId).then((data) => {
setMetadata(camelCaseObject(data));
setLoaded(true);
});
}, [courseId, subSectionId]);
return {
metadata,
loaded,
};
}
export function useExamRedirect(metadata, blocks) {
useEffect(() => {
if (metadata !== null && blocks !== null) {
if (metadata.isTimeLimited) {
global.location.href = blocks[metadata.itemId].lmsWebUrl;
}
}
}, [metadata, blocks]);
}
/**
* Save the position of current unit the subsection
*/
export function usePersistentUnitPosition(courseId, subSectionId, unitId, subSectionMetadata) {
useEffect(() => {
// All values must be defined to function
const hasNeededData = courseId && subSectionId && unitId && subSectionMetadata;
if (!hasNeededData) {
return;
}
const { items, savePosition } = subSectionMetadata;
// A sub-section can individually specify whether positions should be saved
if (!savePosition) {
return;
}
const unitIndex = items.findIndex(({ id }) => unitId === id);
// "position" is a 1-indexed value due to legacy compatibility concerns.
// TODO: Make this value 0-indexed
const newPosition = unitIndex + 1;
// TODO: update the local understanding of the position and
// don't make requests to update the position if they still match?
saveSubSectionPosition(courseId, subSectionId, newPosition);
}, [courseId, subSectionId, unitId, subSectionMetadata]);
}
export function useMissingUnitRedirect(metadata, loaded) {
const { courseId, subSectionId, unitId } = useContext(CourseStructureContext);
useEffect(() => {
if (loaded && metadata.itemId === subSectionId && !unitId) {
// Position comes from the server as a 1-indexed array index. Convert it to 0-indexed.
const position = metadata.position - 1;
const nextUnitId = metadata.items[position].id;
history.push(`/course/${courseId}/${subSectionId}/${nextUnitId}`);
}
}, [loaded, metadata, unitId]);
}

View File

@@ -0,0 +1,11 @@
import { defineMessages } from '@edx/frontend-platform/i18n';
const messages = defineMessages({
'learn.loading.content.lock': {
id: 'learn.loading.content.lock',
defaultMessage: 'Loading locked content messaging...',
description: 'Message shown when an interface about locked content is being loaded',
},
});
export default messages;

View File

@@ -1,43 +0,0 @@
import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl, intlShape, FormattedMessage } from '@edx/frontend-platform/i18n';
import { getLoginRedirectUrl } from '@edx/frontend-platform/auth';
import Alert from '../user-messages/Alert';
import messages from './messages';
function LogistrationAlert({ intl }) {
const signIn = (
<a href={`${getLoginRedirectUrl(global.location.href)}`}>
{intl.formatMessage(messages['learning.logistration.login'])}
</a>
);
// TODO: Pull this registration URL building out into a function, like the login one above.
// This is complicated by the fact that we don't have a REGISTER_URL env variable available.
const register = (
<a href={`${getConfig().LMS_BASE_URL}/register?next=${encodeURIComponent(global.location.href)}`}>
{intl.formatMessage(messages['learning.logistration.register'])}
</a>
);
return (
<Alert type="error">
<FormattedMessage
id="learning.logistration.alert"
description="Prompts the user to sign in or register to see course content."
defaultMessage="Please {signIn} or {register} to see course content."
values={{
signIn,
register,
}}
/>
</Alert>
);
}
LogistrationAlert.propTypes = {
intl: intlShape.isRequired,
};
export default injectIntl(LogistrationAlert);

View File

@@ -1 +0,0 @@
export { default } from './LogistrationAlert';

View File

@@ -1,16 +0,0 @@
import { defineMessages } from '@edx/frontend-platform/i18n';
const messages = defineMessages({
'learning.logistration.login': {
id: 'learning.logistration.login',
defaultMessage: 'sign in',
description: 'Text in a link, prompting the user to log in. Used in "learning.logistration.alert"',
},
'learning.logistration.register': {
id: 'learning.logistration.register',
defaultMessage: 'register',
description: 'Text in a link, prompting the user to create an account. Used in "learning.logistration.alert"',
},
});
export default messages;

View File

@@ -1,45 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Collapsible } from '@edx/paragon';
import { faChevronRight, faChevronDown } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import SequenceLink from './SequenceLink';
import { courseBlocksShape } from '../data/course-blocks';
export default function Chapter({ id, courseUsageKey, models }) {
const { displayName, children } = models[id];
return (
<Collapsible.Advanced className="collapsible-card mb-2">
<Collapsible.Trigger className="collapsible-trigger d-flex align-items-start">
<Collapsible.Visible whenClosed>
<div style={{ minWidth: '1rem' }}>
<FontAwesomeIcon icon={faChevronRight} />
</div>
</Collapsible.Visible>
<Collapsible.Visible whenOpen>
<div style={{ minWidth: '1rem' }}>
<FontAwesomeIcon icon={faChevronDown} />
</div>
</Collapsible.Visible>
<div className="ml-2 flex-grow-1">{displayName}</div>
</Collapsible.Trigger>
<Collapsible.Body className="collapsible-body">
{children.map((sequenceId) => (
<SequenceLink
key={sequenceId}
id={sequenceId}
courseUsageKey={courseUsageKey}
models={models}
/>
))}
</Collapsible.Body>
</Collapsible.Advanced>
);
}
Chapter.propTypes = {
id: PropTypes.string.isRequired,
courseUsageKey: PropTypes.string.isRequired,
models: courseBlocksShape.isRequired,
};

View File

@@ -1,41 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
export default function CourseDates({
start,
end,
enrollmentStart,
enrollmentEnd,
enrollmentMode,
isEnrolled,
}) {
return (
<section>
<h4>Upcoming Dates</h4>
<div><strong>Course Start:</strong><br />{start}</div>
<div><strong>Course End:</strong><br />{end}</div>
<div><strong>Enrollment Start:</strong><br />{enrollmentStart}</div>
<div><strong>Enrollment End:</strong><br />{enrollmentEnd}</div>
<div><strong>Mode:</strong><br />{enrollmentMode}</div>
<div>{isEnrolled ? 'Active Enrollment' : 'Inactive Enrollment'}</div>
</section>
);
}
CourseDates.propTypes = {
start: PropTypes.string,
end: PropTypes.string,
enrollmentStart: PropTypes.string,
enrollmentEnd: PropTypes.string,
enrollmentMode: PropTypes.string,
isEnrolled: PropTypes.bool,
};
CourseDates.defaultProps = {
start: null,
end: null,
enrollmentStart: null,
enrollmentEnd: null,
enrollmentMode: null,
isEnrolled: false,
};

View File

@@ -1,115 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Button } from '@edx/paragon';
import AlertList from '../user-messages/AlertList';
import CourseHeader from '../courseware/course/CourseHeader';
import CourseTabsNavigation from '../courseware/course/CourseTabsNavigation';
import CourseDates from './CourseDates';
import { useLogistrationAlert, useEnrollmentAlert } from '../hooks';
import Chapter from './Chapter';
import { courseBlocksShape } from '../data/course-blocks';
const EnrollmentAlert = React.lazy(() => import('../enrollment-alert'));
const LogistrationAlert = React.lazy(() => import('../logistration-alert'));
export default function Outline({
courseOrg,
courseNumber,
courseName,
courseUsageKey,
courseId,
models,
tabs,
start,
end,
enrollmentStart,
enrollmentEnd,
enrollmentMode,
isEnrolled,
}) {
const course = models[courseId];
useLogistrationAlert();
useEnrollmentAlert(isEnrolled);
return (
<>
<CourseHeader
courseOrg={courseOrg}
courseNumber={courseNumber}
courseName={courseName}
/>
<main className="d-flex flex-column flex-grow-1">
<div className="container-fluid">
<CourseTabsNavigation tabs={tabs} className="mb-3" activeTabSlug="courseware" />
<AlertList
topic="outline"
className="mb-3"
customAlerts={{
clientEnrollmentAlert: EnrollmentAlert,
clientLogistrationAlert: LogistrationAlert,
}}
/>
</div>
<div className="flex-grow-1">
<div className="container-fluid">
<div className="d-flex justify-content-between mb-3">
<h2>{courseName}</h2>
<Button className="btn-primary" type="button">Resume Course</Button>
</div>
<div className="row">
<div className="col col-8">
{course.children.map((chapterId) => (
<Chapter
key={chapterId}
id={chapterId}
courseUsageKey={courseUsageKey}
models={models}
/>
))}
</div>
<div className="col col-4">
<CourseDates
start={start}
end={end}
enrollmentStart={enrollmentStart}
enrollmentEnd={enrollmentEnd}
enrollmentMode={enrollmentMode}
isEnrolled={isEnrolled}
/>
</div>
</div>
</div>
</div>
</main>
</>
);
}
Outline.propTypes = {
courseOrg: PropTypes.string.isRequired,
courseNumber: PropTypes.string.isRequired,
courseName: PropTypes.string.isRequired,
courseUsageKey: PropTypes.string.isRequired,
courseId: PropTypes.string.isRequired,
start: PropTypes.string.isRequired,
end: PropTypes.string.isRequired,
enrollmentStart: PropTypes.string.isRequired,
enrollmentEnd: PropTypes.string.isRequired,
enrollmentMode: PropTypes.string.isRequired,
isEnrolled: PropTypes.bool,
models: courseBlocksShape.isRequired,
tabs: PropTypes.arrayOf(PropTypes.shape({
slug: PropTypes.string.isRequired,
priority: PropTypes.number.isRequired,
title: PropTypes.string.isRequired,
type: PropTypes.string.isRequired,
url: PropTypes.string.isRequired,
})).isRequired,
};
Outline.defaultProps = {
isEnrolled: false,
};

View File

@@ -1,85 +0,0 @@
import React, { useEffect } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { fetchCourseMetadata, courseMetadataShape } from '../data/course-meta';
import { fetchCourseBlocks, courseBlocksShape } from '../data/course-blocks';
import messages from '../courseware/messages';
import PageLoading from '../PageLoading';
import Outline from './Outline';
function OutlineContainer(props) {
const {
intl,
match,
courseId,
blocks: models,
metadata,
} = props;
const { courseUsageKey } = match.params;
useEffect(() => {
props.fetchCourseMetadata(courseUsageKey);
props.fetchCourseBlocks(courseUsageKey);
}, [courseUsageKey]);
const ready = metadata.fetchState === 'loaded' && courseId;
return (
<>
{ready ? (
<Outline
courseOrg={metadata.org}
courseNumber={metadata.number}
courseName={metadata.name}
courseUsageKey={courseUsageKey}
courseId={courseId}
start={metadata.start}
end={metadata.end}
enrollmentStart={metadata.enrollmentStart}
enrollmentEnd={metadata.enrollmentEnd}
enrollmentMode={metadata.enrollmentMode}
isEnrolled={metadata.isEnrolled}
models={models}
tabs={metadata.tabs}
/>
) : (
<PageLoading
srMessage={intl.formatMessage(messages['learn.loading.learning.sequence'])}
/>
)}
</>
);
}
OutlineContainer.propTypes = {
intl: intlShape.isRequired,
courseId: PropTypes.string,
blocks: courseBlocksShape,
metadata: courseMetadataShape,
fetchCourseMetadata: PropTypes.func.isRequired,
fetchCourseBlocks: PropTypes.func.isRequired,
match: PropTypes.shape({
params: PropTypes.shape({
courseUsageKey: PropTypes.string.isRequired,
}).isRequired,
}).isRequired,
};
OutlineContainer.defaultProps = {
blocks: {},
metadata: undefined,
courseId: undefined,
};
const mapStateToProps = state => ({
courseId: state.courseBlocks.root,
metadata: state.courseMeta,
blocks: state.courseBlocks.blocks,
});
export default connect(mapStateToProps, {
fetchCourseMetadata,
fetchCourseBlocks,
})(injectIntl(OutlineContainer));

View File

@@ -1,19 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
import { courseBlocksShape } from '../data/course-blocks';
export default function SequenceLink({ id, courseUsageKey, models }) {
const sequence = models[id];
return (
<div className="ml-4">
<Link to={`/course/${courseUsageKey}/${id}`}>{sequence.displayName}</Link>
</div>
);
}
SequenceLink.propTypes = {
id: PropTypes.string.isRequired,
courseUsageKey: PropTypes.string.isRequired,
models: courseBlocksShape.isRequired,
};

View File

@@ -1,12 +0,0 @@
import { configureStore } from '@reduxjs/toolkit';
import { reducer as courseReducer } from './data/course-meta';
import { reducer as courseBlocksReducer } from './data/course-blocks';
const store = configureStore({
reducer: {
courseMeta: courseReducer,
courseBlocks: courseBlocksReducer,
},
});
export default store;

View File

@@ -1,69 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import {
faExclamationTriangle, faInfoCircle, faCheckCircle, faMinusCircle, faTimes,
} from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Button } from '@edx/paragon';
function getAlertClass(type) {
if (type === 'error') {
return 'alert-warning';
}
if (type === 'danger') {
return 'alert-danger';
}
if (type === 'success') {
return 'alert-success';
}
return 'alert-info';
}
function getAlertIcon(type) {
if (type === 'error') {
return faExclamationTriangle;
}
if (type === 'danger') {
return faMinusCircle;
}
if (type === 'success') {
return faCheckCircle;
}
return faInfoCircle;
}
function Alert({
type, dismissible, children, onDismiss,
}) {
return (
<div className={classNames('alert', { 'alert-dismissible': dismissible }, getAlertClass(type))}>
<div className="d-flex align-items-start">
<div className="mr-2">
<FontAwesomeIcon icon={getAlertIcon(type)} />
</div>
<div role="alert" className="flex-grow-1">
{children}
</div>
</div>
{dismissible && <Button className="close" onClick={onDismiss}><FontAwesomeIcon size="sm" icon={faTimes} /></Button>}
</div>
);
}
Alert.propTypes = {
type: PropTypes.oneOf(['error', 'danger', 'info', 'success']).isRequired,
dismissible: PropTypes.bool,
children: PropTypes.node,
onDismiss: PropTypes.func,
};
Alert.defaultProps = {
dismissible: false,
children: undefined,
onDismiss: null,
};
export default Alert;

View File

@@ -1,55 +0,0 @@
import React, { useContext, useCallback, Suspense } from 'react';
import PropTypes from 'prop-types';
import UserMessagesContext from './UserMessagesContext';
import Alert from './Alert';
export default function AlertList({ topic, className, customAlerts }) {
const { remove, messages } = useContext(UserMessagesContext);
const getAlertComponent = useCallback(
(code) => (customAlerts[code] !== undefined ? customAlerts[code] : Alert),
[customAlerts],
);
const topicMessages = messages.filter(message => !topic || message.topic === topic);
if (topicMessages.length === 0) {
return null;
}
return (
<div className={className}>
{topicMessages.map(message => {
const AlertComponent = getAlertComponent(message.code);
return (
<Suspense key={message.id} fallback={null}>
<AlertComponent
type={message.type}
dismissible={message.dismissible}
onDismiss={() => remove(message.id)}
>
{message.text}
</AlertComponent>
</Suspense>
);
})}
</div>
);
}
AlertList.propTypes = {
className: PropTypes.string,
topic: PropTypes.string,
customAlerts: PropTypes.objectOf(
PropTypes.oneOfType([
PropTypes.object,
PropTypes.func,
PropTypes.node,
]),
),
};
AlertList.defaultProps = {
topic: null,
className: null,
customAlerts: {},
};

View File

@@ -1,5 +0,0 @@
import React from 'react';
const UserMessagesContext = React.createContext({});
export default UserMessagesContext;

View File

@@ -1,55 +0,0 @@
import React, { useState, useRef } from 'react';
import PropTypes from 'prop-types';
import UserMessagesContext from './UserMessagesContext';
export default function UserMessagesProvider({ children }) {
const [messages, setMessages] = useState([]);
const [nextId, setNextId] = useState(1);
const refMessages = useRef(messages);
const add = ({
code, dismissible, text, type, topic, ...others
}) => {
const id = nextId;
refMessages.current = [...refMessages.current, {
code, dismissible, text, type, topic, ...others, id,
}];
setMessages(refMessages.current);
setNextId(nextId + 1);
return id;
};
const remove = id => {
refMessages.current = refMessages.current.filter(message => message.id !== id);
setMessages(refMessages.current);
};
const clear = (topic = null) => {
refMessages.current = topic === null ? [] : refMessages.current.filter(message => message.topic !== topic);
setMessages(refMessages.current);
};
const value = {
add,
remove,
clear,
messages,
};
return (
<UserMessagesContext.Provider value={value}>
{children}
</UserMessagesContext.Provider>
);
}
UserMessagesProvider.propTypes = {
children: PropTypes.node,
};
UserMessagesProvider.defaultProps = {
children: null,
};