Compare commits
76 Commits
KristinAok
...
feat--remo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fbca354df7 | ||
|
|
2230173da8 | ||
|
|
09072f318b | ||
|
|
1f7cb2cc28 | ||
|
|
c6ad7c51d3 | ||
|
|
20d4de09d7 | ||
|
|
5aa857f1de | ||
|
|
3fcc0d87c9 | ||
|
|
0bc7faaa56 | ||
|
|
0889b17e85 | ||
|
|
f57f39a787 | ||
|
|
20390d1e33 | ||
|
|
55b3396acd | ||
|
|
dae0c8931c | ||
|
|
dd6a499cfc | ||
|
|
0c006e28de | ||
|
|
bdba0d2c3c | ||
|
|
965a299f6c | ||
|
|
7cfeaab330 | ||
|
|
76e3173fc4 | ||
|
|
e1d3b91dca | ||
|
|
0592c40496 | ||
|
|
175a40d9fa | ||
|
|
192a58ab51 | ||
|
|
7215db6682 | ||
|
|
cb29902152 | ||
|
|
2932d98976 | ||
|
|
8c0e98ad4f | ||
|
|
8b9dfd2f08 | ||
|
|
e0a81d6cc9 | ||
|
|
9cdaa64f64 | ||
|
|
54d96cc162 | ||
|
|
3da1fb6581 | ||
|
|
268e8b0b40 | ||
|
|
d93cb70966 | ||
|
|
90d6ea8137 | ||
|
|
73302d72cb | ||
|
|
666d9e6b38 | ||
|
|
fcc0cceb8d | ||
|
|
597ecb7b4e | ||
|
|
5ec0fec0ff | ||
|
|
74c75af34d | ||
|
|
9a1966a034 | ||
|
|
1868606ee8 | ||
|
|
70e2aa0203 | ||
|
|
bdfbbc0b75 | ||
|
|
fda9ab6bce | ||
|
|
04cc668e9b | ||
|
|
c91e5d5f58 | ||
|
|
22ca88c981 | ||
|
|
ffd03cb1de | ||
|
|
8cfe4bc099 | ||
|
|
191ef9c7b9 | ||
|
|
ac0813816f | ||
|
|
a614145e6d | ||
|
|
ca9a000fd2 | ||
|
|
9e2b2ec541 | ||
|
|
8552329739 | ||
|
|
90fc5f0024 | ||
|
|
d3c44f3984 | ||
|
|
a607fe4574 | ||
|
|
2d5e1caae7 | ||
|
|
5087353e88 | ||
|
|
2171c28825 | ||
|
|
adde6e3470 | ||
|
|
0d015be97e | ||
|
|
dfbdcee163 | ||
|
|
3ad7b9e95d | ||
|
|
aedee4f847 | ||
|
|
6878ef9fe1 | ||
|
|
04dc5a26ec | ||
|
|
33348eabbd | ||
|
|
c5a383dfdb | ||
|
|
1177c6e2e2 | ||
|
|
d6fdf1512f | ||
|
|
936885707d |
2
.env
2
.env
@@ -4,6 +4,7 @@
|
||||
NODE_ENV='production'
|
||||
ACCESS_TOKEN_COOKIE_NAME=''
|
||||
BASE_URL=''
|
||||
CONTACT_URL=''
|
||||
CREDENTIALS_BASE_URL=''
|
||||
CSRF_TOKEN_API_PATH=''
|
||||
DISCOVERY_API_BASE_URL=''
|
||||
@@ -36,3 +37,4 @@ TWITTER_HASHTAG=''
|
||||
TWITTER_URL=''
|
||||
USER_INFO_COOKIE_NAME=''
|
||||
SESSION_COOKIE_DOMAIN=''
|
||||
ENABLE_NOTICES=''
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
NODE_ENV='development'
|
||||
ACCESS_TOKEN_COOKIE_NAME='edx-jwt-cookie-header-payload'
|
||||
BASE_URL='http://localhost:2000'
|
||||
CONTACT_URL='http://localhost:18000/contact'
|
||||
CREDENTIALS_BASE_URL='http://localhost:18150'
|
||||
CSRF_TOKEN_API_PATH='/csrf/api/v1/token'
|
||||
DISCOVERY_API_BASE_URL='http://localhost:18381'
|
||||
@@ -36,3 +37,4 @@ TWITTER_HASHTAG='myedxjourney'
|
||||
TWITTER_URL='https://twitter.com/edXOnline'
|
||||
USER_INFO_COOKIE_NAME='edx-user-info'
|
||||
SESSION_COOKIE_DOMAIN='localhost'
|
||||
ENABLE_NOTICES=''
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
NODE_ENV='test'
|
||||
ACCESS_TOKEN_COOKIE_NAME='edx-jwt-cookie-header-payload'
|
||||
BASE_URL='http://localhost:2000'
|
||||
CONTACT_URL='http://localhost:18000/contact'
|
||||
CREDENTIALS_BASE_URL='http://localhost:18150'
|
||||
CSRF_TOKEN_API_PATH='/csrf/api/v1/token'
|
||||
DISCOVERY_API_BASE_URL='http://localhost:18381'
|
||||
@@ -35,3 +36,4 @@ TERMS_OF_SERVICE_URL='https://www.edx.org/edx-terms-service'
|
||||
TWITTER_HASHTAG='myedxjourney'
|
||||
TWITTER_URL='https://twitter.com/edXOnline'
|
||||
USER_INFO_COOKIE_NAME='edx-user-info'
|
||||
ENABLE_NOTICES=''
|
||||
|
||||
10
.github/workflows/commitlint.yml
vendored
Normal file
10
.github/workflows/commitlint.yml
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
# Run commitlint on the commit messages in a pull request.
|
||||
|
||||
name: Lint Commit Messages
|
||||
|
||||
on:
|
||||
- pull_request
|
||||
|
||||
jobs:
|
||||
commitlint:
|
||||
uses: edx/.github/.github/workflows/commitlint.yml@master
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -20,3 +20,6 @@ logs
|
||||
|
||||
# Local package dependencies
|
||||
module.config.js
|
||||
|
||||
# Local environment overrides
|
||||
.env.private
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Courseware Page Decisions
|
||||
|
||||
**See [0009-courseware-api-direction.md](0009-courseware-api-direction.md) for updates!**
|
||||
|
||||
## Courseware data loading
|
||||
|
||||
Today we have strictly hierarchical courses - a course contains sections, which contain sequences, which contain units, which contain components.
|
||||
|
||||
62
docs/decisions/0009-courseware-api-direction.md
Normal file
62
docs/decisions/0009-courseware-api-direction.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# Direction of Courseware APIs
|
||||
|
||||
In order to allow for greater flexibility and separation of concerns, we're going to stop using the Course Blocks API for navigational data, and pull that data from the Learning Sequences Outlines API instead. The intention is to give us four distinct layers of courseware that can eventually be composed in different ways:
|
||||
|
||||
* Learning Context Metadata
|
||||
* Learning Context Navigation
|
||||
* Sequence Navigation
|
||||
* Unit Rendering
|
||||
|
||||
Note that "Learning Context" is a generalization of "Course" that includes other things like Content Libraries, Learning Pathways, and potentially other logical groupings of content.
|
||||
|
||||
This is a refinement of [0002-courseware-page-decisions.md](0002-courseware-page-decisions.md). The fundamental layers remain the same, but this document tries to better clarify the boundaries and path forward for these layers. We're not making these layers completely swappable/pluggable now, but we should separate the data access in a way that allows for that in the future.
|
||||
|
||||
## Background
|
||||
|
||||
We currently make four primary requests to the LMS when rendering courseware instructional content:
|
||||
|
||||
1. Course Metadata: `/api/courseware/course/{courseId}` (REST API)
|
||||
2. Course Blocks API: `/api/courses/v2/blocks/?course_id={courseId}` (REST API)
|
||||
3. Sequence Metadata: `/api/courseware/sequence/{sequenceUsageKey}` (REST API)
|
||||
4. Unit: `/xblock/{unitBlockUsageKey}` (rendered in an iframe)
|
||||
|
||||
There is a significant amount of overlap between the Course Blocks API and the others at the moment, since Course Blocks takes a static snapshot of the entire tree of course content at once. There are a few problems with the current arrangement:
|
||||
|
||||
* It's slow and complex. The Course Blocks API can be difficult to maintain and reason about, and trickier to optimize.
|
||||
* Assuming that all course structures are the same makes it difficult to support other content types, like LabXchange Learning Pathways or adaptive content.
|
||||
* The overlap between Course Blocks and the other APIs means that there can be conflicts about the state.
|
||||
|
||||
## Motivating Vision
|
||||
|
||||
We have seen a desire to extend or enhance the courseware experience in various ways:
|
||||
|
||||
Learning Context Navigation
|
||||
* Allowing for shorter, human-readable URLs in courseware.
|
||||
* Smaller courses that do not need the current navigational hierarchy.
|
||||
* LabXchange pathways.
|
||||
|
||||
Sequence Navigation
|
||||
* Adaptive content, where the full list of units is not known up front.
|
||||
* More limited navigation, where content is pushed linearly, without the ability to jump ahead.
|
||||
* Different layouts for content browsing.
|
||||
|
||||
Unit Rendering
|
||||
* Use of QTI content (currently serviced by cc2olx conversion).
|
||||
* Desire to experiment with a next-gen version of XBlock.
|
||||
* Use of entirely LTI units.
|
||||
|
||||
The idea would be to insulate each layer from the layers above and below it. Sequence rendering shouldn't be affected by whether or not it's in a two level hierarchy (Course → Section → Sequence), or a flat one (Course → Sequence). Learning Context Navigation should be able to reference Sequences without caring if a Sequence is an adaptive one or not. Sequences should be able to have a common interface to call Unit iframes, whether those Units are rendering XBlocks or QTI content.
|
||||
|
||||
Note that supporting these types of course structures would require downstream changes in other systems as well (e.g. analytics).
|
||||
|
||||
## Next Step: Removing use of the Course Blocks API.
|
||||
|
||||
The next step in this process is to remove the call to the Course Blocks API, and split its responsibilities across just the existing Learning Sequences Outline and Sequence Metadata APIs. This will involve at least a couple of steps.
|
||||
|
||||
### Complete rollout of Learning Sequences Outline calls.
|
||||
|
||||
We're currently in a transitional state between these APIs where the Learning Sequences Outline calls are only rolled out on a small handful of courses.
|
||||
|
||||
### Shift Sequence and Unit metadata to only come from Sequence Metadata API.
|
||||
|
||||
We currently pull this information from both Course Blocks and the Sequence Metadata API. We can consolidate on just the Sequence Metadata API. There is also server side optimization that can be done with the Sequence Metadata API calls as part of this work.
|
||||
2428
package-lock.json
generated
2428
package-lock.json
generated
@@ -3378,9 +3378,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@edx/frontend-build": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-build/-/frontend-build-8.0.0.tgz",
|
||||
"integrity": "sha512-Z3DAqGiDPzFd0BufNHdI1p0J2wfLAxDrPH/pDZSyj38T/0GBIgfea0fODYwaqP8K3gwO+lLeaJWvOdzgMN/G8g==",
|
||||
"version": "8.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-build/-/frontend-build-8.0.4.tgz",
|
||||
"integrity": "sha512-j1GXQEONHyWgCBRDKuZIIQYh0Uda4sTmDI9kShPgEa93wwLryvUexsoJhrr7gHz+cHF2EdyyR8/3fnZYhZLjdw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/cli": "7.10.5",
|
||||
@@ -3391,6 +3391,7 @@
|
||||
"@babel/preset-env": "7.10.4",
|
||||
"@babel/preset-react": "7.10.4",
|
||||
"@edx/eslint-config": "1.2.0",
|
||||
"@edx/new-relic-source-map-webpack-plugin": "1.0.0",
|
||||
"@pmmmwh/react-refresh-webpack-plugin": "0.5.0-rc.2",
|
||||
"@svgr/webpack": "5.5.0",
|
||||
"autoprefixer": "10.2.6",
|
||||
@@ -3418,7 +3419,6 @@
|
||||
"image-webpack-loader": "7.0.1",
|
||||
"jest": "26.4.2",
|
||||
"mini-css-extract-plugin": "1.6.2",
|
||||
"new-relic-source-map-webpack-plugin": "1.2.0",
|
||||
"postcss": "8.3.5",
|
||||
"postcss-loader": "6.1.1",
|
||||
"postcss-rtlcss": "3.3.4",
|
||||
@@ -3430,10 +3430,10 @@
|
||||
"source-map-loader": "0.2.4",
|
||||
"style-loader": "2.0.0",
|
||||
"url-loader": "4.1.1",
|
||||
"webpack": "5.44.0",
|
||||
"webpack": "5.50.0",
|
||||
"webpack-bundle-analyzer": "3.9.0",
|
||||
"webpack-cli": "4.7.2",
|
||||
"webpack-dev-server": "4.0.0-beta.3",
|
||||
"webpack-cli": "4.8.0",
|
||||
"webpack-dev-server": "4.0.0-rc.1",
|
||||
"webpack-merge": "5.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -3446,6 +3446,12 @@
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"camelcase": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
|
||||
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
|
||||
"dev": true
|
||||
},
|
||||
"chalk": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
@@ -3456,6 +3462,17 @@
|
||||
"supports-color": "^7.1.0"
|
||||
}
|
||||
},
|
||||
"cliui": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
|
||||
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"wrap-ansi": "^6.2.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
@@ -3504,6 +3521,52 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
|
||||
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"y18n": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
|
||||
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
|
||||
"dev": true
|
||||
},
|
||||
"yargs": {
|
||||
"version": "15.4.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
|
||||
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cliui": "^6.0.0",
|
||||
"decamelize": "^1.2.0",
|
||||
"find-up": "^4.1.0",
|
||||
"get-caller-file": "^2.0.1",
|
||||
"require-directory": "^2.1.1",
|
||||
"require-main-filename": "^2.0.0",
|
||||
"set-blocking": "^2.0.0",
|
||||
"string-width": "^4.2.0",
|
||||
"which-module": "^2.0.0",
|
||||
"y18n": "^4.0.0",
|
||||
"yargs-parser": "^18.1.2"
|
||||
}
|
||||
},
|
||||
"yargs-parser": {
|
||||
"version": "18.1.3",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
|
||||
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -3520,9 +3583,9 @@
|
||||
}
|
||||
},
|
||||
"@edx/frontend-enterprise-utils": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-enterprise-utils/-/frontend-enterprise-utils-0.1.7.tgz",
|
||||
"integrity": "sha512-rLS/Fmq+TQPFhy1yMli4e9DsCxGAKcpZp55HvjdiiIbuMpUrWqXuP/UFemL8w45yo9osw6vH0vKhqb14RX8y4A==",
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-enterprise-utils/-/frontend-enterprise-utils-1.0.0.tgz",
|
||||
"integrity": "sha512-EBReGc/Kj7pYpyvy6akd3p2okQ/GRNZpomALgLmhv/kfuF2D9Z1wmmtQ+aJXLtghpHFsmUVsVOtAJxB42orN3g==",
|
||||
"requires": {
|
||||
"@testing-library/react": "11.2.6",
|
||||
"history": "4.10.1",
|
||||
@@ -3596,41 +3659,13 @@
|
||||
"version": "0.5.7",
|
||||
"resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.7.tgz",
|
||||
"integrity": "sha512-ml3lJIq9YjUfM9TUnEPvEYWFSwivwIGBPKpewX7tii7fwCazA8yCioGdqQcNsItPpfFvSJ3VIdMQPj60LJhcQA=="
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
|
||||
},
|
||||
"query-string": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
|
||||
"integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==",
|
||||
"requires": {
|
||||
"decode-uri-component": "^0.2.0",
|
||||
"object-assign": "^4.1.0",
|
||||
"strict-uri-encode": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"strict-uri-encode": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
|
||||
"integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM="
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"requires": {
|
||||
"has-flag": "^4.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@edx/frontend-lib-special-exams": {
|
||||
"version": "1.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-lib-special-exams/-/frontend-lib-special-exams-1.12.0.tgz",
|
||||
"integrity": "sha512-JxbsVlAYpmRmeIU8H7ftEvitrB9A54jAvY2uIFltLA2lTosThmjfq7Rf/F9UUGsJNLDHd77Kqtils5AHD3JiJw==",
|
||||
"version": "1.13.3",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-lib-special-exams/-/frontend-lib-special-exams-1.13.3.tgz",
|
||||
"integrity": "sha512-WTjOPh/Rr6wAKImRdmJaO4g2u+Q0pxw/FLzS7PJ0cE63hoMM8VsVL6diS1Alg01mG5DYXuiX8QyHb9lk0pJzdw==",
|
||||
"requires": {
|
||||
"@fortawesome/fontawesome-svg-core": "1.2.34",
|
||||
"@fortawesome/free-brands-svg-icons": "5.11.2",
|
||||
@@ -3684,12 +3719,12 @@
|
||||
}
|
||||
},
|
||||
"@edx/frontend-platform": {
|
||||
"version": "1.12.3",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-platform/-/frontend-platform-1.12.3.tgz",
|
||||
"integrity": "sha512-ZesfCUJS43CHEaVsakE7BxGpVgTAxmJtn4K6QEz7vWbgXsqBzCMo0msmLRhyFzhma+o86IbWOVpv/zq3rx8wnw==",
|
||||
"version": "1.12.7",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-platform/-/frontend-platform-1.12.7.tgz",
|
||||
"integrity": "sha512-q4QmqVfYjuFCoG0oJthxhSx6rDljaSFZ0rjbQYccBogfwAKi+QedcGgYiPVsiRQN+b+hRleS/r+D0hJ+7zjtfQ==",
|
||||
"requires": {
|
||||
"@cospired/i18n-iso-languages": "2.2.0",
|
||||
"axios": "0.21.1",
|
||||
"axios": "0.21.4",
|
||||
"axios-cache-adapter": "2.7.3",
|
||||
"form-urlencoded": "4.1.4",
|
||||
"glob": "7.1.7",
|
||||
@@ -3707,10 +3742,19 @@
|
||||
"universal-cookie": "4.0.4"
|
||||
}
|
||||
},
|
||||
"@edx/new-relic-source-map-webpack-plugin": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@edx/new-relic-source-map-webpack-plugin/-/new-relic-source-map-webpack-plugin-1.0.0.tgz",
|
||||
"integrity": "sha512-6z7EQxQGl/SvX2ivHxhTEgn56fU3c99kEDPbJdp8s80IWoiMN+Yq46hfCW/J0fiN1qsJsNNNAdwWlgChg/4aLQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@newrelic/publish-sourcemap": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"@edx/paragon": {
|
||||
"version": "16.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@edx/paragon/-/paragon-16.7.0.tgz",
|
||||
"integrity": "sha512-WVcbFKv2OzxAQuiJ8BskrIo+ybv8p7QUEC5Ondg+/eWTt3aYtfYVvmDy7000JwPdsktVS3yKtMoDY2VbdgCNug==",
|
||||
"version": "16.13.3",
|
||||
"resolved": "https://registry.npmjs.org/@edx/paragon/-/paragon-16.13.3.tgz",
|
||||
"integrity": "sha512-wEXi+OE4tzNsBKpT7ZgFtgKkkDRmIB+3UOz7+cv0Ivc7YzOYcgoO6Uy4MvSsVu6eBLuGSsgLxCOk5tAx+Kixag==",
|
||||
"requires": {
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.30",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.14.0",
|
||||
@@ -3809,9 +3853,9 @@
|
||||
}
|
||||
},
|
||||
"@fortawesome/fontawesome-common-types": {
|
||||
"version": "0.2.35",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.35.tgz",
|
||||
"integrity": "sha512-IHUfxSEDS9dDGqYwIW7wTN6tn/O8E0n5PcAHz9cAaBoZw6UpG20IG/YM3NNLaGPwPqgjBAFjIURzqoQs3rrtuw=="
|
||||
"version": "0.2.36",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.36.tgz",
|
||||
"integrity": "sha512-a/7BiSgobHAgBWeN7N0w+lAhInrGxksn13uK7231n2m8EDPE3BMCl9NZLTGrj9ZXfCmC6LM0QLqXidIizVQ6yg=="
|
||||
},
|
||||
"@fortawesome/fontawesome-svg-core": {
|
||||
"version": "1.2.36",
|
||||
@@ -4094,15 +4138,6 @@
|
||||
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
|
||||
"dev": true
|
||||
},
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
@@ -4428,97 +4463,13 @@
|
||||
}
|
||||
},
|
||||
"@newrelic/publish-sourcemap": {
|
||||
"version": "4.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@newrelic/publish-sourcemap/-/publish-sourcemap-4.4.2.tgz",
|
||||
"integrity": "sha512-okPE9K1A5hOHgFm/gfBwxPM8MfBykxbusPEfI20CzS/MboF+4eCx+PS/gfBiDaVf/OrsHPCGTwADkXPPk48a/Q==",
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@newrelic/publish-sourcemap/-/publish-sourcemap-5.0.1.tgz",
|
||||
"integrity": "sha512-eXkc7+RAPJPVBhgYrJWq2nLUDDj1yrgM1yyaT6kDbczZe+NtecOwc3m3yx2WCkVRiAaSANQrKdUsbKkoqt5msg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"superagent": "^3.4.1",
|
||||
"yargs": "^16.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"cliui": {
|
||||
"version": "7.0.4",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
|
||||
"integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"wrap-ansi": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-name": "~1.1.4"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true
|
||||
},
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"y18n": {
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
|
||||
"dev": true
|
||||
},
|
||||
"yargs": {
|
||||
"version": "16.2.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
|
||||
"integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cliui": "^7.0.2",
|
||||
"escalade": "^3.1.1",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"require-directory": "^2.1.1",
|
||||
"string-width": "^4.2.0",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^20.2.2"
|
||||
}
|
||||
},
|
||||
"yargs-parser": {
|
||||
"version": "20.2.9",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
|
||||
"integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"@nodelib/fs.scandir": {
|
||||
@@ -4548,11 +4499,11 @@
|
||||
}
|
||||
},
|
||||
"@pact-foundation/pact": {
|
||||
"version": "9.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@pact-foundation/pact/-/pact-9.16.0.tgz",
|
||||
"integrity": "sha512-UC6xBATLHvfzdMa14IkzvQgmBPxGiLfrWicljpotD9KrIguKQnxnRmpB1vkflcN3kpOLQM4f8HLiSD1HKYeCkw==",
|
||||
"version": "9.16.3",
|
||||
"resolved": "https://registry.npmjs.org/@pact-foundation/pact/-/pact-9.16.3.tgz",
|
||||
"integrity": "sha512-26uhezEbBAbW7gQ0V2QTJp8iSTmgxf9A65J7lCQyTd6P3Sk7omqTL4faio1/UnPlzMaogQjaa8OpmFpSbfXOFg==",
|
||||
"requires": {
|
||||
"@pact-foundation/pact-node": "^10.12.2",
|
||||
"@pact-foundation/pact-node": "^10.13.8",
|
||||
"@types/bluebird": "^3.5.20",
|
||||
"@types/express": "^4.17.11",
|
||||
"bluebird": "~3.5.1",
|
||||
@@ -4564,7 +4515,6 @@
|
||||
"graphql": "^14.0.0",
|
||||
"graphql-tag": "^2.9.1",
|
||||
"http-proxy": "^1.18.1",
|
||||
"http-proxy-middleware": "^0.19.0",
|
||||
"lodash": "^4.17.21",
|
||||
"lodash.isfunction": "3.0.8",
|
||||
"lodash.isnil": "4.0.0",
|
||||
@@ -4585,10 +4535,11 @@
|
||||
}
|
||||
},
|
||||
"@pact-foundation/pact-node": {
|
||||
"version": "10.13.1",
|
||||
"resolved": "https://registry.npmjs.org/@pact-foundation/pact-node/-/pact-node-10.13.1.tgz",
|
||||
"integrity": "sha512-TmBBrBmGTrJ3XxnYeIl3ZqrebmOKy6mw6Hz9Cd3pXeXnfPA4MG3gEbNh6NNZ7F/D998AcV7Nq5dH0o68LOgu1Q==",
|
||||
"version": "10.13.8",
|
||||
"resolved": "https://registry.npmjs.org/@pact-foundation/pact-node/-/pact-node-10.13.8.tgz",
|
||||
"integrity": "sha512-0Jo9b2UNB/qEcsn+fT3+7M68x6DX5lYq82zFIczgbNxVIbuCGkR+xO7u6LnKuO1eyrGfT2WwP7LVLHEJSfMxTw==",
|
||||
"requires": {
|
||||
"@types/needle": "^2.5.1",
|
||||
"@types/pino": "^6.3.5",
|
||||
"@types/q": "1.0.7",
|
||||
"@types/request": "2.48.2",
|
||||
@@ -4603,7 +4554,7 @@
|
||||
"q": "1.5.1",
|
||||
"rimraf": "2.6.2",
|
||||
"sumchecker": "^2.0.2",
|
||||
"tar": "4.4.2",
|
||||
"tar": "^6.1.11",
|
||||
"underscore": "1.12.1",
|
||||
"unixify": "1.0.0",
|
||||
"unzipper": "^0.10.10",
|
||||
@@ -4713,16 +4664,16 @@
|
||||
}
|
||||
},
|
||||
"@popperjs/core": {
|
||||
"version": "2.9.3",
|
||||
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.9.3.tgz",
|
||||
"integrity": "sha512-xDu17cEfh7Kid/d95kB6tZsLOmSWKCZKtprnhVepjsSaCij+lM3mItSJDuuHDMbCWTh8Ejmebwb+KONcCJ0eXQ=="
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.10.1.tgz",
|
||||
"integrity": "sha512-HnUhk1Sy9IuKrxEMdIRCxpIqPw6BFsbYSEUO9p/hNw5sMld/+3OLMWQP80F8/db9qsv3qUjs7ZR5bS/R+iinXw=="
|
||||
},
|
||||
"@reduxjs/toolkit": {
|
||||
"version": "1.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.6.1.tgz",
|
||||
"integrity": "sha512-pa3nqclCJaZPAyBhruQtiRwtTjottRrVJqziVZcWzI73i6L3miLTtUyWfauwv08HWtiXLx1xGyGt+yLFfW/d0A==",
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.6.2.tgz",
|
||||
"integrity": "sha512-HbfI/hOVrAcMGAYsMWxw3UJyIoAS9JTdwddsjlr5w3S50tXhWb+EMyhIw+IAvCVCLETkzdjgH91RjDSYZekVBA==",
|
||||
"requires": {
|
||||
"immer": "^9.0.1",
|
||||
"immer": "^9.0.6",
|
||||
"redux": "^4.1.0",
|
||||
"redux-thunk": "^2.3.0",
|
||||
"reselect": "^4.0.0"
|
||||
@@ -5744,9 +5695,9 @@
|
||||
}
|
||||
},
|
||||
"@testing-library/user-event": {
|
||||
"version": "12.8.3",
|
||||
"resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-12.8.3.tgz",
|
||||
"integrity": "sha512-IR0iWbFkgd56Bu5ZI/ej8yQwrkCv8Qydx6RzwbKz9faXazR/+5tvYKsZQgyXJiwgpcva127YO6JcWy7YlCfofQ==",
|
||||
"version": "13.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.2.1.tgz",
|
||||
"integrity": "sha512-cczlgVl+krjOb3j1625usarNEibI0IFRJrSWX9UsJ1HKYFgCQv9Nb7QAipUDXl3Xdz8NDTsiS78eAkPSxlzTlw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.12.5"
|
||||
@@ -5950,9 +5901,9 @@
|
||||
}
|
||||
},
|
||||
"@types/invariant": {
|
||||
"version": "2.2.34",
|
||||
"resolved": "https://registry.npmjs.org/@types/invariant/-/invariant-2.2.34.tgz",
|
||||
"integrity": "sha512-lYUtmJ9BqUN688fGY1U1HZoWT1/Jrmgigx2loq4ZcJpICECm/Om3V314BxdzypO0u5PORKGMM6x0OXaljV1YFg=="
|
||||
"version": "2.2.35",
|
||||
"resolved": "https://registry.npmjs.org/@types/invariant/-/invariant-2.2.35.tgz",
|
||||
"integrity": "sha512-DxX1V9P8zdJPYQat1gHyY0xj3efl8gnMVjiM9iCY6y27lj+PoQWkgjt8jDqmovPqULkKVpKRg8J36iQiA+EtEg=="
|
||||
},
|
||||
"@types/istanbul-lib-coverage": {
|
||||
"version": "2.0.3",
|
||||
@@ -6002,6 +5953,14 @@
|
||||
"integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/needle": {
|
||||
"version": "2.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/needle/-/needle-2.5.2.tgz",
|
||||
"integrity": "sha512-FSckojxsXODVYE4oJ7q0OjUki27a6gsdIxp2WJHs9oEmXit/0rjzb/NK+tJnKwFMMyR6mzo+1Nyr83ELw3YT+Q==",
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "15.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.2.tgz",
|
||||
@@ -6084,9 +6043,9 @@
|
||||
}
|
||||
},
|
||||
"@types/react-redux": {
|
||||
"version": "7.1.16",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.16.tgz",
|
||||
"integrity": "sha512-f/FKzIrZwZk7YEO9E1yoxIuDNRiDducxkFlkw/GNMGEnK9n4K8wJzlJBghpSuOVDgEUHoDkDF7Gi9lHNQR4siw==",
|
||||
"version": "7.1.18",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.18.tgz",
|
||||
"integrity": "sha512-9iwAsPyJ9DLTRH+OFeIrm9cAbIj1i2ANL3sKQFATqnPWRbg+jEFXyZOKHiQK/N86pNRXbb4HRxAxo0SIX1XwzQ==",
|
||||
"requires": {
|
||||
"@types/hoist-non-react-statics": "^3.3.0",
|
||||
"@types/react": "*",
|
||||
@@ -6420,9 +6379,9 @@
|
||||
}
|
||||
},
|
||||
"@webpack-cli/serve": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.5.1.tgz",
|
||||
"integrity": "sha512-4vSVUiOPJLmr45S8rMGy7WDvpWxfFxfP/Qx/cxZFCfvoypTYpPPL1X8VIZMe0WTA+Jr7blUxwUSEZNkjoMTgSw==",
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.5.2.tgz",
|
||||
"integrity": "sha512-vgJ5OLWadI8aKjDlOH3rb+dYyPd2GTZuQC/Tihjct6F9GpXGZINo3Y/IVuZVTM1eDQB+/AOsjPUWH/WySDaXvw==",
|
||||
"dev": true
|
||||
},
|
||||
"@xtuc/ieee754": {
|
||||
@@ -6468,6 +6427,12 @@
|
||||
"acorn-walk": "^7.1.1"
|
||||
}
|
||||
},
|
||||
"acorn-import-assertions": {
|
||||
"version": "1.7.6",
|
||||
"resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.7.6.tgz",
|
||||
"integrity": "sha512-FlVvVFA1TX6l3lp8VjDnYYq7R1nyW6x3svAt4nDgrWQ9SBaSh9CnbwgSUTasgfNfOG5HlM1ehugCvM+hjo56LA==",
|
||||
"dev": true
|
||||
},
|
||||
"acorn-jsx": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
|
||||
@@ -6784,17 +6749,20 @@
|
||||
"arr-diff": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
|
||||
"integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA="
|
||||
"integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
|
||||
"dev": true
|
||||
},
|
||||
"arr-flatten": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
|
||||
"integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg=="
|
||||
"integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
|
||||
"dev": true
|
||||
},
|
||||
"arr-union": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
|
||||
"integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ="
|
||||
"integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
|
||||
"dev": true
|
||||
},
|
||||
"array-find-index": {
|
||||
"version": "1.0.2",
|
||||
@@ -6839,7 +6807,8 @@
|
||||
"array-unique": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
|
||||
"integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg="
|
||||
"integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
|
||||
"dev": true
|
||||
},
|
||||
"array.prototype.find": {
|
||||
"version": "2.1.1",
|
||||
@@ -6869,7 +6838,8 @@
|
||||
"assign-symbols": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
|
||||
"integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c="
|
||||
"integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
|
||||
"dev": true
|
||||
},
|
||||
"ast-types-flow": {
|
||||
"version": "0.0.7",
|
||||
@@ -6918,7 +6888,8 @@
|
||||
"atob": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
|
||||
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg=="
|
||||
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
|
||||
"dev": true
|
||||
},
|
||||
"atomic-sleep": {
|
||||
"version": "1.0.0",
|
||||
@@ -6945,11 +6916,11 @@
|
||||
"integrity": "sha512-SA5mXJWrId1TaQjfxUYghbqQ/hYioKmLJvPJyDuYRtXXenFNMjj4hSSt1Cf1xsuXSXrtxrVC5Ot4eU6cOtBDdA=="
|
||||
},
|
||||
"axios": {
|
||||
"version": "0.21.1",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz",
|
||||
"integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==",
|
||||
"version": "0.21.4",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
|
||||
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
|
||||
"requires": {
|
||||
"follow-redirects": "^1.10.0"
|
||||
"follow-redirects": "^1.14.0"
|
||||
}
|
||||
},
|
||||
"axios-cache-adapter": {
|
||||
@@ -6962,13 +6933,14 @@
|
||||
}
|
||||
},
|
||||
"axios-mock-adapter": {
|
||||
"version": "1.19.0",
|
||||
"resolved": "https://registry.npmjs.org/axios-mock-adapter/-/axios-mock-adapter-1.19.0.tgz",
|
||||
"integrity": "sha512-D+0U4LNPr7WroiBDvWilzTMYPYTuZlbo6BI8YHZtj7wYQS8NkARlP9KBt8IWWHTQJ0q/8oZ0ClPBtKCCkx8cQg==",
|
||||
"version": "1.20.0",
|
||||
"resolved": "https://registry.npmjs.org/axios-mock-adapter/-/axios-mock-adapter-1.20.0.tgz",
|
||||
"integrity": "sha512-shZRhTjLP0WWdcvHKf3rH3iW9deb3UdKbdnKUoHmmsnBhVXN3sjPJM6ZvQ2r/ywgvBVQrMnjrSyQab60G1sr2w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"is-buffer": "^2.0.3"
|
||||
"is-blob": "^2.1.0",
|
||||
"is-buffer": "^2.0.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"is-buffer": {
|
||||
@@ -7307,6 +7279,7 @@
|
||||
"version": "0.11.2",
|
||||
"resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
|
||||
"integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cache-base": "^1.0.1",
|
||||
"class-utils": "^0.3.5",
|
||||
@@ -7321,6 +7294,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
|
||||
"integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-descriptor": "^1.0.0"
|
||||
}
|
||||
@@ -7329,6 +7303,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
|
||||
"integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^6.0.0"
|
||||
}
|
||||
@@ -7337,6 +7312,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
|
||||
"integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^6.0.0"
|
||||
}
|
||||
@@ -7345,6 +7321,7 @@
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
|
||||
"integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-accessor-descriptor": "^1.0.0",
|
||||
"is-data-descriptor": "^1.0.0",
|
||||
@@ -7379,9 +7356,9 @@
|
||||
}
|
||||
},
|
||||
"big-integer": {
|
||||
"version": "1.6.48",
|
||||
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz",
|
||||
"integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w=="
|
||||
"version": "1.6.49",
|
||||
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.49.tgz",
|
||||
"integrity": "sha512-KJ7VhqH+f/BOt9a3yMwJNmcZjG53ijWMTjSAGMveQWyLwqIiwkjNP5PFgDob3Snnx86SjDj6I89fIbv0dkQeNw=="
|
||||
},
|
||||
"big.js": {
|
||||
"version": "5.2.2",
|
||||
@@ -7870,6 +7847,7 @@
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
|
||||
"integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"arr-flatten": "^1.1.0",
|
||||
"array-unique": "^0.3.2",
|
||||
@@ -7887,6 +7865,7 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
|
||||
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-extendable": "^0.1.0"
|
||||
}
|
||||
@@ -7905,16 +7884,24 @@
|
||||
"dev": true
|
||||
},
|
||||
"browserslist": {
|
||||
"version": "4.16.7",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.7.tgz",
|
||||
"integrity": "sha512-7I4qVwqZltJ7j37wObBe3SoTz+nS8APaNcrBOlgoirb6/HbEU2XxW/LpUDTCngM6iauwFqmRTuOMfyKnFGY5JA==",
|
||||
"version": "4.16.8",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.8.tgz",
|
||||
"integrity": "sha512-sc2m9ohR/49sWEbPj14ZSSZqp+kbi16aLao42Hmn3Z8FpjuMaq2xCA2l4zl9ITfyzvnvyE0hcg62YkIGKxgaNQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"caniuse-lite": "^1.0.30001248",
|
||||
"colorette": "^1.2.2",
|
||||
"electron-to-chromium": "^1.3.793",
|
||||
"caniuse-lite": "^1.0.30001251",
|
||||
"colorette": "^1.3.0",
|
||||
"electron-to-chromium": "^1.3.811",
|
||||
"escalade": "^3.1.1",
|
||||
"node-releases": "^1.1.73"
|
||||
"node-releases": "^1.1.75"
|
||||
},
|
||||
"dependencies": {
|
||||
"colorette": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/colorette/-/colorette-1.3.0.tgz",
|
||||
"integrity": "sha512-ecORCqbSFP7Wm8Y6lyqMJjexBQqXSF7SSeaTyGGphogUjBlFP9m9o08wy86HL2uB7fMTxtOUzLMk7ogKcxMg1w==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"bser": {
|
||||
@@ -7999,6 +7986,7 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
|
||||
"integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"collection-visit": "^1.0.0",
|
||||
"component-emitter": "^1.2.1",
|
||||
@@ -8333,9 +8321,9 @@
|
||||
}
|
||||
},
|
||||
"chownr": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
|
||||
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
|
||||
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="
|
||||
},
|
||||
"chrome-trace-event": {
|
||||
"version": "1.0.3",
|
||||
@@ -8359,6 +8347,7 @@
|
||||
"version": "0.3.6",
|
||||
"resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
|
||||
"integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"arr-union": "^3.1.0",
|
||||
"define-property": "^0.2.5",
|
||||
@@ -8370,6 +8359,7 @@
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
|
||||
"integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-descriptor": "^0.1.0"
|
||||
}
|
||||
@@ -8452,13 +8442,6 @@
|
||||
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
|
||||
"dev": true
|
||||
},
|
||||
"colors": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
|
||||
"integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
|
||||
@@ -8493,25 +8476,14 @@
|
||||
"dev": true
|
||||
},
|
||||
"cliui": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
|
||||
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
|
||||
"version": "7.0.4",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
|
||||
"integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"wrap-ansi": "^6.2.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"
|
||||
}
|
||||
}
|
||||
"wrap-ansi": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"clone-deep": {
|
||||
@@ -8581,6 +8553,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
|
||||
"integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"map-visit": "^1.0.0",
|
||||
"object-visit": "^1.0.0"
|
||||
@@ -8600,9 +8573,9 @@
|
||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
|
||||
},
|
||||
"colord": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/colord/-/colord-2.6.0.tgz",
|
||||
"integrity": "sha512-8yMrtE20ZxH1YWvvSoeJFtvqY+GIAOfU+mZ3jx7ZSiEMasnAmNqD1BKUP3CuCWcy/XHgcXkLW6YU8C35nhOYVg==",
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/colord/-/colord-2.7.0.tgz",
|
||||
"integrity": "sha512-pZJBqsHz+pYyw3zpX6ZRXWoCHM1/cvFikY9TV8G3zcejCaKE0lhankoj8iScyrrePA8C7yJ5FStfA9zbcOnw7Q==",
|
||||
"dev": true
|
||||
},
|
||||
"colorette": {
|
||||
@@ -8611,6 +8584,12 @@
|
||||
"integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==",
|
||||
"dev": true
|
||||
},
|
||||
"colors": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
|
||||
"integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
|
||||
"dev": true
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
@@ -8634,7 +8613,8 @@
|
||||
"component-emitter": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
|
||||
"integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
|
||||
"integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==",
|
||||
"dev": true
|
||||
},
|
||||
"compressible": {
|
||||
"version": "2.0.18",
|
||||
@@ -8816,17 +8796,18 @@
|
||||
"copy-descriptor": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
|
||||
"integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40="
|
||||
"integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
|
||||
"dev": true
|
||||
},
|
||||
"core-js": {
|
||||
"version": "3.16.1",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.16.1.tgz",
|
||||
"integrity": "sha512-AAkP8i35EbefU+JddyWi12AWE9f2N/qr/pwnDtWz4nyUIBGMJPX99ANFFRSw6FefM374lDujdtLDyhN2A/btHw=="
|
||||
"version": "3.16.4",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.16.4.tgz",
|
||||
"integrity": "sha512-Tq4GVE6XCjE+hcyW6hPy0ofN3hwtLudz5ZRdrlCnsnD/xkm/PWQRudzYHiKgZKUcefV6Q57fhDHjZHJP5dpfSg=="
|
||||
},
|
||||
"core-js-compat": {
|
||||
"version": "3.16.1",
|
||||
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.16.1.tgz",
|
||||
"integrity": "sha512-NHXQXvRbd4nxp9TEmooTJLUf94ySUG6+DSsscBpTftN1lQLQ4LjnWvc7AoIo4UjDsFF3hB8Uh5LLCRRdaiT5MQ==",
|
||||
"version": "3.16.2",
|
||||
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.16.2.tgz",
|
||||
"integrity": "sha512-4lUshXtBXsdmp8cDWh6KKiHUg40AjiuPD3bOWkNVsr1xkAhpUqCjaZ8lB1bKx9Gb5fXcbRbFJ4f4qpRIRTuJqQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"browserslist": "^4.16.7",
|
||||
@@ -8998,9 +8979,9 @@
|
||||
}
|
||||
},
|
||||
"cssnano-preset-default": {
|
||||
"version": "5.1.3",
|
||||
"resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.1.3.tgz",
|
||||
"integrity": "sha512-qo9tX+t4yAAZ/yagVV3b+QBKeLklQbmgR3wI7mccrDcR+bEk9iHgZN1E7doX68y9ThznLya3RDmR+nc7l6/2WQ==",
|
||||
"version": "5.1.4",
|
||||
"resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.1.4.tgz",
|
||||
"integrity": "sha512-sPpQNDQBI3R/QsYxQvfB4mXeEcWuw0wGtKtmS5eg8wudyStYMgKOQT39G07EbW1LB56AOYrinRS9f0ig4Y3MhQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"css-declaration-sorter": "^6.0.3",
|
||||
@@ -9015,7 +8996,7 @@
|
||||
"postcss-merge-longhand": "^5.0.2",
|
||||
"postcss-merge-rules": "^5.0.2",
|
||||
"postcss-minify-font-values": "^5.0.1",
|
||||
"postcss-minify-gradients": "^5.0.1",
|
||||
"postcss-minify-gradients": "^5.0.2",
|
||||
"postcss-minify-params": "^5.0.1",
|
||||
"postcss-minify-selectors": "^5.1.0",
|
||||
"postcss-normalize-charset": "^5.0.1",
|
||||
@@ -9150,9 +9131,9 @@
|
||||
}
|
||||
},
|
||||
"dateformat": {
|
||||
"version": "4.5.1",
|
||||
"resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.5.1.tgz",
|
||||
"integrity": "sha512-OD0TZ+B7yP7ZgpJf5K2DIbj3FZvFvxgFUuaqA/V5zTjAtAAXZ1E8bktHxmAGs4x5b7PflqA9LeQ84Og7wYtF7Q=="
|
||||
"version": "4.6.3",
|
||||
"resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz",
|
||||
"integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA=="
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
@@ -9461,6 +9442,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"define-lazy-prop": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
|
||||
"integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==",
|
||||
"dev": true
|
||||
},
|
||||
"define-properties": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
|
||||
@@ -9473,6 +9460,7 @@
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
|
||||
"integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-descriptor": "^1.0.2",
|
||||
"isobject": "^3.0.1"
|
||||
@@ -9482,6 +9470,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
|
||||
"integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^6.0.0"
|
||||
}
|
||||
@@ -9490,6 +9479,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
|
||||
"integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^6.0.0"
|
||||
}
|
||||
@@ -9498,6 +9488,7 @@
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
|
||||
"integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-accessor-descriptor": "^1.0.0",
|
||||
"is-data-descriptor": "^1.0.0",
|
||||
@@ -9878,9 +9869,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"electron-to-chromium": {
|
||||
"version": "1.3.803",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.803.tgz",
|
||||
"integrity": "sha512-tmRK9qB8Zs8eLMtTBp+w2zVS9MUe62gQQQHjYdAc5Zljam3ZIokNb+vZLPRz9RCREp6EFRwyhOFwbt1fEriQ2Q==",
|
||||
"version": "1.3.813",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.813.tgz",
|
||||
"integrity": "sha512-YcSRImHt6JZZ2sSuQ4Bzajtk98igQ0iKkksqlzZLzbh4p0OIyJRSvUbsgqfcR8txdfsoYCc4ym306t4p2kP/aw==",
|
||||
"dev": true
|
||||
},
|
||||
"email-prop-type": {
|
||||
@@ -9990,20 +9981,20 @@
|
||||
}
|
||||
},
|
||||
"es-check": {
|
||||
"version": "5.2.4",
|
||||
"resolved": "https://registry.npmjs.org/es-check/-/es-check-5.2.4.tgz",
|
||||
"integrity": "sha512-FZ3qAJ9hwguqPvGGagaKAVDnusSkezeHbiKNM5rOepOjloeVuX2e6meMxQ+mKcnWbAFucCG7fszNrzUT8bvHcQ==",
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/es-check/-/es-check-6.0.0.tgz",
|
||||
"integrity": "sha512-FwWQ03GgWL8HplV7gWMDtpR5I+n0K/JYLnLoMDw2DrdsfxF2jV+dtpqo0sIVFeoHgYjEeWkb0ntZvEah7R7T1w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"acorn": "^6.4.1",
|
||||
"caporal": "1.4.0",
|
||||
"glob": "^7.1.2"
|
||||
"acorn": "^8.4.1",
|
||||
"caporal": "^1.4.0",
|
||||
"glob": "^7.1.7"
|
||||
},
|
||||
"dependencies": {
|
||||
"acorn": {
|
||||
"version": "6.4.2",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz",
|
||||
"integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==",
|
||||
"version": "8.4.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz",
|
||||
"integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
@@ -10156,6 +10147,12 @@
|
||||
"v8-compile-cache": "^2.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
|
||||
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
|
||||
"dev": true
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
|
||||
@@ -10194,6 +10191,15 @@
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
||||
"dev": true
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
|
||||
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^4.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -10220,9 +10226,9 @@
|
||||
}
|
||||
},
|
||||
"eslint-import-resolver-node": {
|
||||
"version": "0.3.5",
|
||||
"resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.5.tgz",
|
||||
"integrity": "sha512-XMoPKjSpXbkeJ7ZZ9icLnJMTY5Mc1kZbCakHquaFsXPpyWOwK0TK6CODO+0ca54UoM9LKOxyUNnoVZRl8TeaAg==",
|
||||
"version": "0.3.6",
|
||||
"resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz",
|
||||
"integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"debug": "^3.2.7",
|
||||
@@ -10683,6 +10689,7 @@
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
|
||||
"integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"debug": "^2.3.3",
|
||||
"define-property": "^0.2.5",
|
||||
@@ -10697,6 +10704,7 @@
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
|
||||
"integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-descriptor": "^0.1.0"
|
||||
}
|
||||
@@ -10705,6 +10713,7 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
|
||||
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-extendable": "^0.1.0"
|
||||
}
|
||||
@@ -10811,11 +10820,11 @@
|
||||
}
|
||||
},
|
||||
"ext": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz",
|
||||
"integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==",
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz",
|
||||
"integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==",
|
||||
"requires": {
|
||||
"type": "^2.0.0"
|
||||
"type": "^2.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"type": {
|
||||
@@ -10856,6 +10865,7 @@
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
|
||||
"integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assign-symbols": "^1.0.0",
|
||||
"is-extendable": "^1.0.1"
|
||||
@@ -10865,6 +10875,7 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
|
||||
"integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-plain-object": "^2.0.4"
|
||||
}
|
||||
@@ -10886,6 +10897,7 @@
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
|
||||
"integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"array-unique": "^0.3.2",
|
||||
"define-property": "^1.0.0",
|
||||
@@ -10901,6 +10913,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
|
||||
"integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-descriptor": "^1.0.0"
|
||||
}
|
||||
@@ -10909,6 +10922,7 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
|
||||
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-extendable": "^0.1.0"
|
||||
}
|
||||
@@ -10917,6 +10931,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
|
||||
"integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^6.0.0"
|
||||
}
|
||||
@@ -10925,6 +10940,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
|
||||
"integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^6.0.0"
|
||||
}
|
||||
@@ -10933,6 +10949,7 @@
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
|
||||
"integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-accessor-descriptor": "^1.0.0",
|
||||
"is-data-descriptor": "^1.0.0",
|
||||
@@ -11033,14 +11050,14 @@
|
||||
"dev": true
|
||||
},
|
||||
"fast-redact": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.0.1.tgz",
|
||||
"integrity": "sha512-kYpn4Y/valC9MdrISg47tZOpYBNoTXKgT9GYXFpHN/jYFs+lFkPoisY+LcBODdKVMY96ATzvzsWv+ES/4Kmufw=="
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.0.2.tgz",
|
||||
"integrity": "sha512-YN+CYfCVRVMUZOUPeinHNKgytM1wPI/C/UCLEi56EsY2dwwvI00kIJHJoI7pMVqGoMew8SMZ2SSfHKHULHXDsg=="
|
||||
},
|
||||
"fast-safe-stringify": {
|
||||
"version": "2.0.8",
|
||||
"resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.8.tgz",
|
||||
"integrity": "sha512-lXatBjf3WPjmWD6DpIZxkeSsCOwqI0maYMpgDlx8g4U2qi4lbjA9oH/HD2a87G+KfsUmo5WbJFmqBZlPxtptag=="
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
|
||||
"integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA=="
|
||||
},
|
||||
"fast-url-parser": {
|
||||
"version": "1.1.3",
|
||||
@@ -11072,10 +11089,15 @@
|
||||
"integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==",
|
||||
"dev": true
|
||||
},
|
||||
"fastify-warning": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/fastify-warning/-/fastify-warning-0.2.0.tgz",
|
||||
"integrity": "sha512-s1EQguBw/9qtc1p/WTY4eq9WMRIACkj+HTcOIK1in4MV5aFaQC9ZCIt0dJ7pr5bIf4lPpHvAtP2ywpTNgs7hqw=="
|
||||
},
|
||||
"fastq": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.1.tgz",
|
||||
"integrity": "sha512-HOnr8Mc60eNYl1gzwp6r5RoUyAn5/glBolUzP/Ez6IFVPMPirxn/9phgL6zhOtaTy7ISwPvQ+wT+hfcRZh/bzw==",
|
||||
"version": "1.12.0",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.12.0.tgz",
|
||||
"integrity": "sha512-VNX0QkHK3RsXVKr9KrlUv/FoTa0NdbYoHHl7uXHv2rzyHSlxjdNAKug2twd9luJxpcyNeAgf5iPPMutJO67Dfg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"reusify": "^1.0.4"
|
||||
@@ -11184,6 +11206,7 @@
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
|
||||
"integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"extend-shallow": "^2.0.1",
|
||||
"is-number": "^3.0.0",
|
||||
@@ -11195,6 +11218,7 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
|
||||
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-extendable": "^0.1.0"
|
||||
}
|
||||
@@ -11280,9 +11304,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"focus-lock": {
|
||||
"version": "0.9.1",
|
||||
"resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-0.9.1.tgz",
|
||||
"integrity": "sha512-/2Nj60Cps6yOLSO+CkVbeSKfwfns5XbX6HOedIK9PdzODP04N9c3xqOcPXayN0WsT9YjJvAnXmI0NdqNIDf5Kw==",
|
||||
"version": "0.9.2",
|
||||
"resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-0.9.2.tgz",
|
||||
"integrity": "sha512-YtHxjX7a0IC0ZACL5wsX8QdncXofWpGPNoVMuI/nZUrPGp6LmNI6+D5j0pPj+v8Kw5EpweA+T5yImK0rnWf7oQ==",
|
||||
"requires": {
|
||||
"tslib": "^2.0.3"
|
||||
},
|
||||
@@ -11307,7 +11331,8 @@
|
||||
"for-in": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
|
||||
"integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA="
|
||||
"integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
|
||||
"dev": true
|
||||
},
|
||||
"foreach": {
|
||||
"version": "2.0.5",
|
||||
@@ -11373,6 +11398,7 @@
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
|
||||
"integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"map-cache": "^0.2.2"
|
||||
}
|
||||
@@ -11455,11 +11481,11 @@
|
||||
}
|
||||
},
|
||||
"fs-minipass": {
|
||||
"version": "1.2.7",
|
||||
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz",
|
||||
"integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==",
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
|
||||
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
|
||||
"requires": {
|
||||
"minipass": "^2.6.0"
|
||||
"minipass": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"fs-monkey": {
|
||||
@@ -11603,7 +11629,8 @@
|
||||
"get-value": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
|
||||
"integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg="
|
||||
"integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
|
||||
"dev": true
|
||||
},
|
||||
"gifsicle": {
|
||||
"version": "5.2.0",
|
||||
@@ -11849,9 +11876,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
|
||||
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
|
||||
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -11959,6 +11986,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
|
||||
"integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"get-value": "^2.0.6",
|
||||
"has-values": "^1.0.0",
|
||||
@@ -11969,6 +11997,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
|
||||
"integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-number": "^3.0.0",
|
||||
"kind-of": "^4.0.0"
|
||||
@@ -11978,6 +12007,7 @@
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
|
||||
"integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-buffer": "^1.1.5"
|
||||
}
|
||||
@@ -11990,12 +12020,6 @@
|
||||
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
|
||||
"dev": true
|
||||
},
|
||||
"hex-color-regex": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz",
|
||||
"integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==",
|
||||
"dev": true
|
||||
},
|
||||
"history": {
|
||||
"version": "4.10.1",
|
||||
"resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz",
|
||||
@@ -12079,18 +12103,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"hsl-regex": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz",
|
||||
"integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=",
|
||||
"dev": true
|
||||
},
|
||||
"hsla-regex": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz",
|
||||
"integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=",
|
||||
"dev": true
|
||||
},
|
||||
"html-encoding-sniffer": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz",
|
||||
@@ -12264,17 +12276,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"http-proxy-middleware": {
|
||||
"version": "0.19.1",
|
||||
"resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz",
|
||||
"integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==",
|
||||
"requires": {
|
||||
"http-proxy": "^1.17.0",
|
||||
"is-glob": "^4.0.0",
|
||||
"lodash": "^4.17.11",
|
||||
"micromatch": "^3.1.10"
|
||||
}
|
||||
},
|
||||
"https-proxy-agent": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
|
||||
@@ -12309,9 +12310,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"husky": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/husky/-/husky-7.0.1.tgz",
|
||||
"integrity": "sha512-gceRaITVZ+cJH9sNHqx5tFwbzlLCVxtVZcusME8JYQ8Edy5mpGDOqD8QBCdMhpyo9a+JXddnujQ4rpY2Ff9SJA==",
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/husky/-/husky-7.0.2.tgz",
|
||||
"integrity": "sha512-8yKEWNX4z2YsofXAMT7KvA1g8p+GxtB1ffV8XtpAEGuXNAbCV5wdNKH+qTpw8SM9fh4aMPDR+yQuKfgnreyZlg==",
|
||||
"dev": true
|
||||
},
|
||||
"hyphenate-style-name": {
|
||||
@@ -12748,9 +12749,9 @@
|
||||
"integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps="
|
||||
},
|
||||
"immer": {
|
||||
"version": "9.0.5",
|
||||
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.5.tgz",
|
||||
"integrity": "sha512-2WuIehr2y4lmYz9gaQzetPR2ECniCifk4ORaQbU3g5EalLt+0IVTosEPJ5BoYl/75ky2mivzdRzV8wWgQGOSYQ=="
|
||||
"version": "9.0.6",
|
||||
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.6.tgz",
|
||||
"integrity": "sha512-G95ivKpy+EvVAnAab4fVa4YGYn24J1SpEktnJX7JJ45Bd7xqME/SCplFzYFmTbrkwZbQ4xJK1xMTUYBkN6pWsQ=="
|
||||
},
|
||||
"import-fresh": {
|
||||
"version": "3.3.0",
|
||||
@@ -12879,15 +12880,6 @@
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true
|
||||
},
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -13011,6 +13003,7 @@
|
||||
"version": "0.1.6",
|
||||
"resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
|
||||
"integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^3.0.2"
|
||||
},
|
||||
@@ -13019,6 +13012,7 @@
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
|
||||
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-buffer": "^1.1.5"
|
||||
}
|
||||
@@ -13054,6 +13048,12 @@
|
||||
"binary-extensions": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"is-blob": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-blob/-/is-blob-2.1.0.tgz",
|
||||
"integrity": "sha512-SZ/fTft5eUhQM6oF/ZaASFDEdbFVe89Imltn9uZr03wdKMcWNVYSMjQPFtg05QuNkt5l5c135ElvXEQG0rk4tw==",
|
||||
"dev": true
|
||||
},
|
||||
"is-boolean-object": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz",
|
||||
@@ -13081,28 +13081,6 @@
|
||||
"ci-info": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"is-color-stop": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz",
|
||||
"integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"css-color-names": "^0.0.4",
|
||||
"hex-color-regex": "^1.1.0",
|
||||
"hsl-regex": "^1.0.0",
|
||||
"hsla-regex": "^1.0.0",
|
||||
"rgb-regex": "^1.0.1",
|
||||
"rgba-regex": "^1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"css-color-names": {
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz",
|
||||
"integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"is-core-module": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz",
|
||||
@@ -13135,6 +13113,7 @@
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
|
||||
"integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^3.0.2"
|
||||
},
|
||||
@@ -13143,6 +13122,7 @@
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
|
||||
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-buffer": "^1.1.5"
|
||||
}
|
||||
@@ -13158,6 +13138,7 @@
|
||||
"version": "0.1.6",
|
||||
"resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
|
||||
"integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-accessor-descriptor": "^0.1.6",
|
||||
"is-data-descriptor": "^0.1.4",
|
||||
@@ -13167,7 +13148,8 @@
|
||||
"kind-of": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
|
||||
"integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw=="
|
||||
"integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -13180,12 +13162,14 @@
|
||||
"is-extendable": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
|
||||
"integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik="
|
||||
"integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
|
||||
"dev": true
|
||||
},
|
||||
"is-extglob": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
|
||||
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
|
||||
"dev": true
|
||||
},
|
||||
"is-finite": {
|
||||
"version": "1.1.0",
|
||||
@@ -13237,6 +13221,7 @@
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
|
||||
"integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-extglob": "^2.1.1"
|
||||
}
|
||||
@@ -13299,6 +13284,7 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
|
||||
"integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^3.0.2"
|
||||
},
|
||||
@@ -13307,6 +13293,7 @@
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
|
||||
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-buffer": "^1.1.5"
|
||||
}
|
||||
@@ -13360,6 +13347,7 @@
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
|
||||
"integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"isobject": "^3.0.1"
|
||||
}
|
||||
@@ -13507,7 +13495,8 @@
|
||||
"is-windows": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
|
||||
"integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA=="
|
||||
"integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
|
||||
"dev": true
|
||||
},
|
||||
"is-wsl": {
|
||||
"version": "2.2.0",
|
||||
@@ -13531,7 +13520,8 @@
|
||||
"isobject": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
|
||||
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
|
||||
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
|
||||
"dev": true
|
||||
},
|
||||
"isstream": {
|
||||
"version": "0.1.2",
|
||||
@@ -13674,49 +13664,49 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@jest/console": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@jest/console/-/console-27.0.6.tgz",
|
||||
"integrity": "sha512-fMlIBocSHPZ3JxgWiDNW/KPj6s+YRd0hicb33IrmelCcjXo/pXPwvuiKFmZz+XuqI/1u7nbUK10zSsWL/1aegg==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/console/-/console-27.1.0.tgz",
|
||||
"integrity": "sha512-+Vl+xmLwAXLNlqT61gmHEixeRbS4L8MUzAjtpBCOPWH+izNI/dR16IeXjkXJdRtIVWVSf9DO1gdp67B1XorZhQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/types": "^27.1.0",
|
||||
"@types/node": "*",
|
||||
"chalk": "^4.0.0",
|
||||
"jest-message-util": "^27.0.6",
|
||||
"jest-util": "^27.0.6",
|
||||
"jest-message-util": "^27.1.0",
|
||||
"jest-util": "^27.1.0",
|
||||
"slash": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"@jest/core": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@jest/core/-/core-27.0.6.tgz",
|
||||
"integrity": "sha512-SsYBm3yhqOn5ZLJCtccaBcvD/ccTLCeuDv8U41WJH/V1MW5eKUkeMHT9U+Pw/v1m1AIWlnIW/eM2XzQr0rEmow==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/core/-/core-27.1.0.tgz",
|
||||
"integrity": "sha512-3l9qmoknrlCFKfGdrmiQiPne+pUR4ALhKwFTYyOeKw6egfDwJkO21RJ1xf41rN8ZNFLg5W+w6+P4fUqq4EMRWA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/console": "^27.0.6",
|
||||
"@jest/reporters": "^27.0.6",
|
||||
"@jest/test-result": "^27.0.6",
|
||||
"@jest/transform": "^27.0.6",
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/console": "^27.1.0",
|
||||
"@jest/reporters": "^27.1.0",
|
||||
"@jest/test-result": "^27.1.0",
|
||||
"@jest/transform": "^27.1.0",
|
||||
"@jest/types": "^27.1.0",
|
||||
"@types/node": "*",
|
||||
"ansi-escapes": "^4.2.1",
|
||||
"chalk": "^4.0.0",
|
||||
"emittery": "^0.8.1",
|
||||
"exit": "^0.1.2",
|
||||
"graceful-fs": "^4.2.4",
|
||||
"jest-changed-files": "^27.0.6",
|
||||
"jest-config": "^27.0.6",
|
||||
"jest-haste-map": "^27.0.6",
|
||||
"jest-message-util": "^27.0.6",
|
||||
"jest-changed-files": "^27.1.0",
|
||||
"jest-config": "^27.1.0",
|
||||
"jest-haste-map": "^27.1.0",
|
||||
"jest-message-util": "^27.1.0",
|
||||
"jest-regex-util": "^27.0.6",
|
||||
"jest-resolve": "^27.0.6",
|
||||
"jest-resolve-dependencies": "^27.0.6",
|
||||
"jest-runner": "^27.0.6",
|
||||
"jest-runtime": "^27.0.6",
|
||||
"jest-snapshot": "^27.0.6",
|
||||
"jest-util": "^27.0.6",
|
||||
"jest-validate": "^27.0.6",
|
||||
"jest-watcher": "^27.0.6",
|
||||
"jest-resolve": "^27.1.0",
|
||||
"jest-resolve-dependencies": "^27.1.0",
|
||||
"jest-runner": "^27.1.0",
|
||||
"jest-runtime": "^27.1.0",
|
||||
"jest-snapshot": "^27.1.0",
|
||||
"jest-util": "^27.1.0",
|
||||
"jest-validate": "^27.1.0",
|
||||
"jest-watcher": "^27.1.0",
|
||||
"micromatch": "^4.0.4",
|
||||
"p-each-series": "^2.1.0",
|
||||
"rimraf": "^3.0.0",
|
||||
@@ -13725,53 +13715,53 @@
|
||||
}
|
||||
},
|
||||
"@jest/environment": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.0.6.tgz",
|
||||
"integrity": "sha512-4XywtdhwZwCpPJ/qfAkqExRsERW+UaoSRStSHCCiQTUpoYdLukj+YJbQSFrZjhlUDRZeNiU9SFH0u7iNimdiIg==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.1.0.tgz",
|
||||
"integrity": "sha512-wRp50aAMY2w1U2jP1G32d6FUVBNYqmk8WaGkiIEisU48qyDV0WPtw3IBLnl7orBeggveommAkuijY+RzVnNDOQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/fake-timers": "^27.0.6",
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/fake-timers": "^27.1.0",
|
||||
"@jest/types": "^27.1.0",
|
||||
"@types/node": "*",
|
||||
"jest-mock": "^27.0.6"
|
||||
"jest-mock": "^27.1.0"
|
||||
}
|
||||
},
|
||||
"@jest/fake-timers": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.0.6.tgz",
|
||||
"integrity": "sha512-sqd+xTWtZ94l3yWDKnRTdvTeZ+A/V7SSKrxsrOKSqdyddb9CeNRF8fbhAU0D7ZJBpTTW2nbp6MftmKJDZfW2LQ==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.1.0.tgz",
|
||||
"integrity": "sha512-22Zyn8il8DzpS+30jJNVbTlm7vAtnfy1aYvNeOEHloMlGy1PCYLHa4PWlSws0hvNsMM5bON6GISjkLoQUV3oMA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/types": "^27.1.0",
|
||||
"@sinonjs/fake-timers": "^7.0.2",
|
||||
"@types/node": "*",
|
||||
"jest-message-util": "^27.0.6",
|
||||
"jest-mock": "^27.0.6",
|
||||
"jest-util": "^27.0.6"
|
||||
"jest-message-util": "^27.1.0",
|
||||
"jest-mock": "^27.1.0",
|
||||
"jest-util": "^27.1.0"
|
||||
}
|
||||
},
|
||||
"@jest/globals": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.0.6.tgz",
|
||||
"integrity": "sha512-DdTGCP606rh9bjkdQ7VvChV18iS7q0IMJVP1piwTWyWskol4iqcVwthZmoJEf7obE1nc34OpIyoVGPeqLC+ryw==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.1.0.tgz",
|
||||
"integrity": "sha512-73vLV4aNHAlAgjk0/QcSIzzCZSqVIPbmFROJJv9D3QUR7BI4f517gVdJpSrCHxuRH3VZFhe0yGG/tmttlMll9g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/environment": "^27.0.6",
|
||||
"@jest/types": "^27.0.6",
|
||||
"expect": "^27.0.6"
|
||||
"@jest/environment": "^27.1.0",
|
||||
"@jest/types": "^27.1.0",
|
||||
"expect": "^27.1.0"
|
||||
}
|
||||
},
|
||||
"@jest/reporters": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.0.6.tgz",
|
||||
"integrity": "sha512-TIkBt09Cb2gptji3yJXb3EE+eVltW6BjO7frO7NEfjI9vSIYoISi5R3aI3KpEDXlB1xwB+97NXIqz84qYeYsfA==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.1.0.tgz",
|
||||
"integrity": "sha512-5T/zlPkN2HnK3Sboeg64L5eC8iiaZueLpttdktWTJsvALEtP2YMkC5BQxwjRWQACG9SwDmz+XjjkoxXUDMDgdw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@bcoe/v8-coverage": "^0.2.3",
|
||||
"@jest/console": "^27.0.6",
|
||||
"@jest/test-result": "^27.0.6",
|
||||
"@jest/transform": "^27.0.6",
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/console": "^27.1.0",
|
||||
"@jest/test-result": "^27.1.0",
|
||||
"@jest/transform": "^27.1.0",
|
||||
"@jest/types": "^27.1.0",
|
||||
"chalk": "^4.0.0",
|
||||
"collect-v8-coverage": "^1.0.0",
|
||||
"exit": "^0.1.2",
|
||||
@@ -13782,10 +13772,10 @@
|
||||
"istanbul-lib-report": "^3.0.0",
|
||||
"istanbul-lib-source-maps": "^4.0.0",
|
||||
"istanbul-reports": "^3.0.2",
|
||||
"jest-haste-map": "^27.0.6",
|
||||
"jest-resolve": "^27.0.6",
|
||||
"jest-util": "^27.0.6",
|
||||
"jest-worker": "^27.0.6",
|
||||
"jest-haste-map": "^27.1.0",
|
||||
"jest-resolve": "^27.1.0",
|
||||
"jest-util": "^27.1.0",
|
||||
"jest-worker": "^27.1.0",
|
||||
"slash": "^3.0.0",
|
||||
"source-map": "^0.6.0",
|
||||
"string-length": "^4.0.1",
|
||||
@@ -13805,45 +13795,45 @@
|
||||
}
|
||||
},
|
||||
"@jest/test-result": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.0.6.tgz",
|
||||
"integrity": "sha512-ja/pBOMTufjX4JLEauLxE3LQBPaI2YjGFtXexRAjt1I/MbfNlMx0sytSX3tn5hSLzQsR3Qy2rd0hc1BWojtj9w==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.1.0.tgz",
|
||||
"integrity": "sha512-Aoz00gpDL528ODLghat3QSy6UBTD5EmmpjrhZZMK/v1Q2/rRRqTGnFxHuEkrD4z/Py96ZdOHxIWkkCKRpmnE1A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/console": "^27.0.6",
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/console": "^27.1.0",
|
||||
"@jest/types": "^27.1.0",
|
||||
"@types/istanbul-lib-coverage": "^2.0.0",
|
||||
"collect-v8-coverage": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"@jest/test-sequencer": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.0.6.tgz",
|
||||
"integrity": "sha512-bISzNIApazYOlTHDum9PwW22NOyDa6VI31n6JucpjTVM0jD6JDgqEZ9+yn575nDdPF0+4csYDxNNW13NvFQGZA==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.1.0.tgz",
|
||||
"integrity": "sha512-lnCWawDr6Z1DAAK9l25o3AjmKGgcutq1iIbp+hC10s/HxnB8ZkUsYq1FzjOoxxZ5hW+1+AthBtvS4x9yno3V1A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/test-result": "^27.0.6",
|
||||
"@jest/test-result": "^27.1.0",
|
||||
"graceful-fs": "^4.2.4",
|
||||
"jest-haste-map": "^27.0.6",
|
||||
"jest-runtime": "^27.0.6"
|
||||
"jest-haste-map": "^27.1.0",
|
||||
"jest-runtime": "^27.1.0"
|
||||
}
|
||||
},
|
||||
"@jest/transform": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.0.6.tgz",
|
||||
"integrity": "sha512-rj5Dw+mtIcntAUnMlW/Vju5mr73u8yg+irnHwzgtgoeI6cCPOvUwQ0D1uQtc/APmWgvRweEb1g05pkUpxH3iCA==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.1.0.tgz",
|
||||
"integrity": "sha512-ZRGCA2ZEVJ00ubrhkTG87kyLbN6n55g1Ilq0X9nJb5bX3MhMp3O6M7KG+LvYu+nZRqG5cXsQnJEdZbdpTAV8pQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/core": "^7.1.0",
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/types": "^27.1.0",
|
||||
"babel-plugin-istanbul": "^6.0.0",
|
||||
"chalk": "^4.0.0",
|
||||
"convert-source-map": "^1.4.0",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
"graceful-fs": "^4.2.4",
|
||||
"jest-haste-map": "^27.0.6",
|
||||
"jest-haste-map": "^27.1.0",
|
||||
"jest-regex-util": "^27.0.6",
|
||||
"jest-util": "^27.0.6",
|
||||
"jest-util": "^27.1.0",
|
||||
"micromatch": "^4.0.4",
|
||||
"pirates": "^4.0.1",
|
||||
"slash": "^3.0.0",
|
||||
@@ -13852,9 +13842,9 @@
|
||||
}
|
||||
},
|
||||
"@jest/types": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
|
||||
"integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/types/-/types-27.1.0.tgz",
|
||||
"integrity": "sha512-pRP5cLIzN7I7Vp6mHKRSaZD7YpBTK7hawx5si8trMKqk4+WOdK8NEKOTO2G8PKWD1HbKMVckVB6/XHh/olhf2g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/istanbul-lib-coverage": "^2.0.0",
|
||||
@@ -13882,12 +13872,6 @@
|
||||
"@types/yargs-parser": "*"
|
||||
}
|
||||
},
|
||||
"acorn": {
|
||||
"version": "8.4.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz",
|
||||
"integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==",
|
||||
"dev": true
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
@@ -13908,13 +13892,13 @@
|
||||
}
|
||||
},
|
||||
"babel-jest": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.0.6.tgz",
|
||||
"integrity": "sha512-iTJyYLNc4wRofASmofpOc5NK9QunwMk+TLFgGXsTFS8uEqmd8wdI7sga0FPe2oVH3b5Agt/EAK1QjPEuKL8VfA==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.1.0.tgz",
|
||||
"integrity": "sha512-6NrdqzaYemALGCuR97QkC/FkFIEBWP5pw5TMJoUHZTVXyOgocujp6A0JE2V6gE0HtqAAv6VKU/nI+OCR1Z4gHA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/transform": "^27.0.6",
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/transform": "^27.1.0",
|
||||
"@jest/types": "^27.1.0",
|
||||
"@types/babel__core": "^7.1.14",
|
||||
"babel-plugin-istanbul": "^6.0.0",
|
||||
"babel-preset-jest": "^27.0.6",
|
||||
@@ -13976,17 +13960,6 @@
|
||||
"integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==",
|
||||
"dev": true
|
||||
},
|
||||
"cliui": {
|
||||
"version": "7.0.4",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
|
||||
"integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"wrap-ansi": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
@@ -14043,16 +14016,16 @@
|
||||
}
|
||||
},
|
||||
"expect": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/expect/-/expect-27.0.6.tgz",
|
||||
"integrity": "sha512-psNLt8j2kwg42jGBDSfAlU49CEZxejN1f1PlANWDZqIhBOVU/c2Pm888FcjWJzFewhIsNWfZJeLjUjtKGiPuSw==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/expect/-/expect-27.1.0.tgz",
|
||||
"integrity": "sha512-9kJngV5hOJgkFil4F/uXm3hVBubUK2nERVfvqNNwxxuW8ZOUwSTTSysgfzckYtv/LBzj/LJXbiAF7okHCXgdug==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/types": "^27.1.0",
|
||||
"ansi-styles": "^5.0.0",
|
||||
"jest-get-type": "^27.0.6",
|
||||
"jest-matcher-utils": "^27.0.6",
|
||||
"jest-message-util": "^27.0.6",
|
||||
"jest-matcher-utils": "^27.1.0",
|
||||
"jest-message-util": "^27.1.0",
|
||||
"jest-regex-util": "^27.0.6"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -14073,17 +14046,6 @@
|
||||
"to-regex-range": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"form-data": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
|
||||
"integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"mime-types": "^2.1.12"
|
||||
}
|
||||
},
|
||||
"fsevents": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||
@@ -14103,12 +14065,6 @@
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||
"dev": true
|
||||
},
|
||||
"human-signals": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
|
||||
"integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
|
||||
"dev": true
|
||||
},
|
||||
"is-ci": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz",
|
||||
@@ -14131,75 +14087,75 @@
|
||||
"dev": true
|
||||
},
|
||||
"jest-changed-files": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.0.6.tgz",
|
||||
"integrity": "sha512-BuL/ZDauaq5dumYh5y20sn4IISnf1P9A0TDswTxUi84ORGtVa86ApuBHqICL0vepqAnZiY6a7xeSPWv2/yy4eA==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.1.0.tgz",
|
||||
"integrity": "sha512-eRcb13TfQw0xiV2E98EmiEgs9a5uaBIqJChyl0G7jR9fCIvGjXovnDS6Zbku3joij4tXYcSK4SE1AXqOlUxjWg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/types": "^27.1.0",
|
||||
"execa": "^5.0.0",
|
||||
"throat": "^6.0.1"
|
||||
}
|
||||
},
|
||||
"jest-cli": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.0.6.tgz",
|
||||
"integrity": "sha512-qUUVlGb9fdKir3RDE+B10ULI+LQrz+MCflEH2UJyoUjoHHCbxDrMxSzjQAPUMsic4SncI62ofYCcAvW6+6rhhg==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.1.0.tgz",
|
||||
"integrity": "sha512-h6zPUOUu+6oLDrXz0yOWY2YXvBLk8gQinx4HbZ7SF4V3HzasQf+ncoIbKENUMwXyf54/6dBkYXvXJos+gOHYZw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/core": "^27.0.6",
|
||||
"@jest/test-result": "^27.0.6",
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/core": "^27.1.0",
|
||||
"@jest/test-result": "^27.1.0",
|
||||
"@jest/types": "^27.1.0",
|
||||
"chalk": "^4.0.0",
|
||||
"exit": "^0.1.2",
|
||||
"graceful-fs": "^4.2.4",
|
||||
"import-local": "^3.0.2",
|
||||
"jest-config": "^27.0.6",
|
||||
"jest-util": "^27.0.6",
|
||||
"jest-validate": "^27.0.6",
|
||||
"jest-config": "^27.1.0",
|
||||
"jest-util": "^27.1.0",
|
||||
"jest-validate": "^27.1.0",
|
||||
"prompts": "^2.0.1",
|
||||
"yargs": "^16.0.3"
|
||||
}
|
||||
},
|
||||
"jest-config": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.0.6.tgz",
|
||||
"integrity": "sha512-JZRR3I1Plr2YxPBhgqRspDE2S5zprbga3swYNrvY3HfQGu7p/GjyLOqwrYad97tX3U3mzT53TPHVmozacfP/3w==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.1.0.tgz",
|
||||
"integrity": "sha512-GMo7f76vMYUA3b3xOdlcKeKQhKcBIgurjERO2hojo0eLkKPGcw7fyIoanH+m6KOP2bLad+fGnF8aWOJYxzNPeg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/core": "^7.1.0",
|
||||
"@jest/test-sequencer": "^27.0.6",
|
||||
"@jest/types": "^27.0.6",
|
||||
"babel-jest": "^27.0.6",
|
||||
"@jest/test-sequencer": "^27.1.0",
|
||||
"@jest/types": "^27.1.0",
|
||||
"babel-jest": "^27.1.0",
|
||||
"chalk": "^4.0.0",
|
||||
"deepmerge": "^4.2.2",
|
||||
"glob": "^7.1.1",
|
||||
"graceful-fs": "^4.2.4",
|
||||
"is-ci": "^3.0.0",
|
||||
"jest-circus": "^27.0.6",
|
||||
"jest-environment-jsdom": "^27.0.6",
|
||||
"jest-environment-node": "^27.0.6",
|
||||
"jest-circus": "^27.1.0",
|
||||
"jest-environment-jsdom": "^27.1.0",
|
||||
"jest-environment-node": "^27.1.0",
|
||||
"jest-get-type": "^27.0.6",
|
||||
"jest-jasmine2": "^27.0.6",
|
||||
"jest-jasmine2": "^27.1.0",
|
||||
"jest-regex-util": "^27.0.6",
|
||||
"jest-resolve": "^27.0.6",
|
||||
"jest-runner": "^27.0.6",
|
||||
"jest-util": "^27.0.6",
|
||||
"jest-validate": "^27.0.6",
|
||||
"jest-resolve": "^27.1.0",
|
||||
"jest-runner": "^27.1.0",
|
||||
"jest-util": "^27.1.0",
|
||||
"jest-validate": "^27.1.0",
|
||||
"micromatch": "^4.0.4",
|
||||
"pretty-format": "^27.0.6"
|
||||
"pretty-format": "^27.1.0"
|
||||
}
|
||||
},
|
||||
"jest-diff": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.0.6.tgz",
|
||||
"integrity": "sha512-Z1mqgkTCSYaFgwTlP/NUiRzdqgxmmhzHY1Tq17zL94morOHfHu3K4bgSgl+CR4GLhpV8VxkuOYuIWnQ9LnFqmg==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.1.0.tgz",
|
||||
"integrity": "sha512-rjfopEYl58g/SZTsQFmspBODvMSytL16I+cirnScWTLkQVXYVZfxm78DFfdIIXc05RCYuGjxJqrdyG4PIFzcJg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "^4.0.0",
|
||||
"diff-sequences": "^27.0.6",
|
||||
"jest-get-type": "^27.0.6",
|
||||
"pretty-format": "^27.0.6"
|
||||
"pretty-format": "^27.1.0"
|
||||
}
|
||||
},
|
||||
"jest-docblock": {
|
||||
@@ -14212,45 +14168,45 @@
|
||||
}
|
||||
},
|
||||
"jest-each": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.0.6.tgz",
|
||||
"integrity": "sha512-m6yKcV3bkSWrUIjxkE9OC0mhBZZdhovIW5ergBYirqnkLXkyEn3oUUF/QZgyecA1cF1QFyTE8bRRl8Tfg1pfLA==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.1.0.tgz",
|
||||
"integrity": "sha512-K/cNvQlmDqQMRHF8CaQ0XPzCfjP5HMJc2bIJglrIqI9fjwpNqITle63IWE+wq4p+3v+iBgh7Wq0IdGpLx5xjDg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/types": "^27.1.0",
|
||||
"chalk": "^4.0.0",
|
||||
"jest-get-type": "^27.0.6",
|
||||
"jest-util": "^27.0.6",
|
||||
"pretty-format": "^27.0.6"
|
||||
"jest-util": "^27.1.0",
|
||||
"pretty-format": "^27.1.0"
|
||||
}
|
||||
},
|
||||
"jest-environment-jsdom": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.0.6.tgz",
|
||||
"integrity": "sha512-FvetXg7lnXL9+78H+xUAsra3IeZRTiegA3An01cWeXBspKXUhAwMM9ycIJ4yBaR0L7HkoMPaZsozCLHh4T8fuw==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.1.0.tgz",
|
||||
"integrity": "sha512-JbwOcOxh/HOtsj56ljeXQCUJr3ivnaIlM45F5NBezFLVYdT91N5UofB1ux2B1CATsQiudcHdgTaeuqGXJqjJYQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/environment": "^27.0.6",
|
||||
"@jest/fake-timers": "^27.0.6",
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/environment": "^27.1.0",
|
||||
"@jest/fake-timers": "^27.1.0",
|
||||
"@jest/types": "^27.1.0",
|
||||
"@types/node": "*",
|
||||
"jest-mock": "^27.0.6",
|
||||
"jest-util": "^27.0.6",
|
||||
"jest-mock": "^27.1.0",
|
||||
"jest-util": "^27.1.0",
|
||||
"jsdom": "^16.6.0"
|
||||
}
|
||||
},
|
||||
"jest-environment-node": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.0.6.tgz",
|
||||
"integrity": "sha512-+Vi6yLrPg/qC81jfXx3IBlVnDTI6kmRr08iVa2hFCWmJt4zha0XW7ucQltCAPhSR0FEKEoJ3i+W4E6T0s9is0w==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.1.0.tgz",
|
||||
"integrity": "sha512-JIyJ8H3wVyM4YCXp7njbjs0dIT87yhGlrXCXhDKNIg1OjurXr6X38yocnnbXvvNyqVTqSI4M9l+YfPKueqL1lw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/environment": "^27.0.6",
|
||||
"@jest/fake-timers": "^27.0.6",
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/environment": "^27.1.0",
|
||||
"@jest/fake-timers": "^27.1.0",
|
||||
"@jest/types": "^27.1.0",
|
||||
"@types/node": "*",
|
||||
"jest-mock": "^27.0.6",
|
||||
"jest-util": "^27.0.6"
|
||||
"jest-mock": "^27.1.0",
|
||||
"jest-util": "^27.1.0"
|
||||
}
|
||||
},
|
||||
"jest-get-type": {
|
||||
@@ -14260,12 +14216,12 @@
|
||||
"dev": true
|
||||
},
|
||||
"jest-haste-map": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.0.6.tgz",
|
||||
"integrity": "sha512-4ldjPXX9h8doB2JlRzg9oAZ2p6/GpQUNAeiYXqcpmrKbP0Qev0wdZlxSMOmz8mPOEnt4h6qIzXFLDi8RScX/1w==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.1.0.tgz",
|
||||
"integrity": "sha512-7mz6LopSe+eA6cTFMf10OfLLqRoIPvmMyz5/OnSXnHO7hB0aDP1iIeLWCXzAcYU5eIJVpHr12Bk9yyq2fTW9vg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/types": "^27.1.0",
|
||||
"@types/graceful-fs": "^4.1.2",
|
||||
"@types/node": "*",
|
||||
"anymatch": "^3.0.3",
|
||||
@@ -14274,84 +14230,84 @@
|
||||
"graceful-fs": "^4.2.4",
|
||||
"jest-regex-util": "^27.0.6",
|
||||
"jest-serializer": "^27.0.6",
|
||||
"jest-util": "^27.0.6",
|
||||
"jest-worker": "^27.0.6",
|
||||
"jest-util": "^27.1.0",
|
||||
"jest-worker": "^27.1.0",
|
||||
"micromatch": "^4.0.4",
|
||||
"walker": "^1.0.7"
|
||||
}
|
||||
},
|
||||
"jest-jasmine2": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.0.6.tgz",
|
||||
"integrity": "sha512-cjpH2sBy+t6dvCeKBsHpW41mjHzXgsavaFMp+VWRf0eR4EW8xASk1acqmljFtK2DgyIECMv2yCdY41r2l1+4iA==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.1.0.tgz",
|
||||
"integrity": "sha512-Z/NIt0wBDg3przOW2FCWtYjMn3Ip68t0SL60agD/e67jlhTyV3PIF8IzT9ecwqFbeuUSO2OT8WeJgHcalDGFzQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/traverse": "^7.1.0",
|
||||
"@jest/environment": "^27.0.6",
|
||||
"@jest/environment": "^27.1.0",
|
||||
"@jest/source-map": "^27.0.6",
|
||||
"@jest/test-result": "^27.0.6",
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/test-result": "^27.1.0",
|
||||
"@jest/types": "^27.1.0",
|
||||
"@types/node": "*",
|
||||
"chalk": "^4.0.0",
|
||||
"co": "^4.6.0",
|
||||
"expect": "^27.0.6",
|
||||
"expect": "^27.1.0",
|
||||
"is-generator-fn": "^2.0.0",
|
||||
"jest-each": "^27.0.6",
|
||||
"jest-matcher-utils": "^27.0.6",
|
||||
"jest-message-util": "^27.0.6",
|
||||
"jest-runtime": "^27.0.6",
|
||||
"jest-snapshot": "^27.0.6",
|
||||
"jest-util": "^27.0.6",
|
||||
"pretty-format": "^27.0.6",
|
||||
"jest-each": "^27.1.0",
|
||||
"jest-matcher-utils": "^27.1.0",
|
||||
"jest-message-util": "^27.1.0",
|
||||
"jest-runtime": "^27.1.0",
|
||||
"jest-snapshot": "^27.1.0",
|
||||
"jest-util": "^27.1.0",
|
||||
"pretty-format": "^27.1.0",
|
||||
"throat": "^6.0.1"
|
||||
}
|
||||
},
|
||||
"jest-leak-detector": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.0.6.tgz",
|
||||
"integrity": "sha512-2/d6n2wlH5zEcdctX4zdbgX8oM61tb67PQt4Xh8JFAIy6LRKUnX528HulkaG6nD5qDl5vRV1NXejCe1XRCH5gQ==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.1.0.tgz",
|
||||
"integrity": "sha512-oHvSkz1E80VyeTKBvZNnw576qU+cVqRXUD3/wKXh1zpaki47Qty2xeHg2HKie9Hqcd2l4XwircgNOWb/NiGqdA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"jest-get-type": "^27.0.6",
|
||||
"pretty-format": "^27.0.6"
|
||||
"pretty-format": "^27.1.0"
|
||||
}
|
||||
},
|
||||
"jest-matcher-utils": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.0.6.tgz",
|
||||
"integrity": "sha512-OFgF2VCQx9vdPSYTHWJ9MzFCehs20TsyFi6bIHbk5V1u52zJOnvF0Y/65z3GLZHKRuTgVPY4Z6LVePNahaQ+tA==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.1.0.tgz",
|
||||
"integrity": "sha512-VmAudus2P6Yt/JVBRdTPFhUzlIN8DYJd+et5Rd9QDsO/Z82Z4iwGjo43U8Z+PTiz8CBvKvlb6Fh3oKy39hykkQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "^4.0.0",
|
||||
"jest-diff": "^27.0.6",
|
||||
"jest-diff": "^27.1.0",
|
||||
"jest-get-type": "^27.0.6",
|
||||
"pretty-format": "^27.0.6"
|
||||
"pretty-format": "^27.1.0"
|
||||
}
|
||||
},
|
||||
"jest-message-util": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.0.6.tgz",
|
||||
"integrity": "sha512-rBxIs2XK7rGy+zGxgi+UJKP6WqQ+KrBbD1YMj517HYN3v2BG66t3Xan3FWqYHKZwjdB700KiAJ+iES9a0M+ixw==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.1.0.tgz",
|
||||
"integrity": "sha512-Eck8NFnJ5Sg36R9XguD65cf2D5+McC+NF5GIdEninoabcuoOfWrID5qJhufq5FB0DRKoiyxB61hS7MKoMD0trQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.12.13",
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/types": "^27.1.0",
|
||||
"@types/stack-utils": "^2.0.0",
|
||||
"chalk": "^4.0.0",
|
||||
"graceful-fs": "^4.2.4",
|
||||
"micromatch": "^4.0.4",
|
||||
"pretty-format": "^27.0.6",
|
||||
"pretty-format": "^27.1.0",
|
||||
"slash": "^3.0.0",
|
||||
"stack-utils": "^2.0.3"
|
||||
}
|
||||
},
|
||||
"jest-mock": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.0.6.tgz",
|
||||
"integrity": "sha512-lzBETUoK8cSxts2NYXSBWT+EJNzmUVtVVwS1sU9GwE1DLCfGsngg+ZVSIe0yd0ZSm+y791esiuo+WSwpXJQ5Bw==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.1.0.tgz",
|
||||
"integrity": "sha512-iT3/Yhu7DwAg/0HvvLCqLvrTKTRMyJlrrfJYWzuLSf9RCAxBoIXN3HoymZxMnYsC3eD8ewGbUa9jUknwBenx2w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/types": "^27.1.0",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
@@ -14362,92 +14318,94 @@
|
||||
"dev": true
|
||||
},
|
||||
"jest-resolve": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.0.6.tgz",
|
||||
"integrity": "sha512-yKmIgw2LgTh7uAJtzv8UFHGF7Dm7XfvOe/LQ3Txv101fLM8cx2h1QVwtSJ51Q/SCxpIiKfVn6G2jYYMDNHZteA==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.1.0.tgz",
|
||||
"integrity": "sha512-TXvzrLyPg0vLOwcWX38ZGYeEztSEmW+cQQKqc4HKDUwun31wsBXwotRlUz4/AYU/Fq4GhbMd/ileIWZEtcdmIA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/types": "^27.1.0",
|
||||
"chalk": "^4.0.0",
|
||||
"escalade": "^3.1.1",
|
||||
"graceful-fs": "^4.2.4",
|
||||
"jest-haste-map": "^27.1.0",
|
||||
"jest-pnp-resolver": "^1.2.2",
|
||||
"jest-util": "^27.0.6",
|
||||
"jest-validate": "^27.0.6",
|
||||
"jest-util": "^27.1.0",
|
||||
"jest-validate": "^27.1.0",
|
||||
"resolve": "^1.20.0",
|
||||
"slash": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"jest-resolve-dependencies": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.0.6.tgz",
|
||||
"integrity": "sha512-mg9x9DS3BPAREWKCAoyg3QucCr0n6S8HEEsqRCKSPjPcu9HzRILzhdzY3imsLoZWeosEbJZz6TKasveczzpJZA==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.1.0.tgz",
|
||||
"integrity": "sha512-Kq5XuDAELuBnrERrjFYEzu/A+i2W7l9HnPWqZEeKGEQ7m1R+6ndMbdXCVCx29Se1qwLZLgvoXwinB3SPIaitMQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/types": "^27.1.0",
|
||||
"jest-regex-util": "^27.0.6",
|
||||
"jest-snapshot": "^27.0.6"
|
||||
"jest-snapshot": "^27.1.0"
|
||||
}
|
||||
},
|
||||
"jest-runner": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.0.6.tgz",
|
||||
"integrity": "sha512-W3Bz5qAgaSChuivLn+nKOgjqNxM7O/9JOJoKDCqThPIg2sH/d4A/lzyiaFgnb9V1/w29Le11NpzTJSzga1vyYQ==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.1.0.tgz",
|
||||
"integrity": "sha512-ZWPKr9M5w5gDplz1KsJ6iRmQaDT/yyAFLf18fKbb/+BLWsR1sCNC2wMT0H7pP3gDcBz0qZ6aJraSYUNAGSJGaw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/console": "^27.0.6",
|
||||
"@jest/environment": "^27.0.6",
|
||||
"@jest/test-result": "^27.0.6",
|
||||
"@jest/transform": "^27.0.6",
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/console": "^27.1.0",
|
||||
"@jest/environment": "^27.1.0",
|
||||
"@jest/test-result": "^27.1.0",
|
||||
"@jest/transform": "^27.1.0",
|
||||
"@jest/types": "^27.1.0",
|
||||
"@types/node": "*",
|
||||
"chalk": "^4.0.0",
|
||||
"emittery": "^0.8.1",
|
||||
"exit": "^0.1.2",
|
||||
"graceful-fs": "^4.2.4",
|
||||
"jest-docblock": "^27.0.6",
|
||||
"jest-environment-jsdom": "^27.0.6",
|
||||
"jest-environment-node": "^27.0.6",
|
||||
"jest-haste-map": "^27.0.6",
|
||||
"jest-leak-detector": "^27.0.6",
|
||||
"jest-message-util": "^27.0.6",
|
||||
"jest-resolve": "^27.0.6",
|
||||
"jest-runtime": "^27.0.6",
|
||||
"jest-util": "^27.0.6",
|
||||
"jest-worker": "^27.0.6",
|
||||
"jest-environment-jsdom": "^27.1.0",
|
||||
"jest-environment-node": "^27.1.0",
|
||||
"jest-haste-map": "^27.1.0",
|
||||
"jest-leak-detector": "^27.1.0",
|
||||
"jest-message-util": "^27.1.0",
|
||||
"jest-resolve": "^27.1.0",
|
||||
"jest-runtime": "^27.1.0",
|
||||
"jest-util": "^27.1.0",
|
||||
"jest-worker": "^27.1.0",
|
||||
"source-map-support": "^0.5.6",
|
||||
"throat": "^6.0.1"
|
||||
}
|
||||
},
|
||||
"jest-runtime": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.0.6.tgz",
|
||||
"integrity": "sha512-BhvHLRVfKibYyqqEFkybsznKwhrsu7AWx2F3y9G9L95VSIN3/ZZ9vBpm/XCS2bS+BWz3sSeNGLzI3TVQ0uL85Q==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.1.0.tgz",
|
||||
"integrity": "sha512-okiR2cpGjY0RkWmUGGado6ETpFOi9oG3yV0CioYdoktkVxy5Hv0WRLWnJFuArSYS8cHMCNcceUUMGiIfgxCO9A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/console": "^27.0.6",
|
||||
"@jest/environment": "^27.0.6",
|
||||
"@jest/fake-timers": "^27.0.6",
|
||||
"@jest/globals": "^27.0.6",
|
||||
"@jest/console": "^27.1.0",
|
||||
"@jest/environment": "^27.1.0",
|
||||
"@jest/fake-timers": "^27.1.0",
|
||||
"@jest/globals": "^27.1.0",
|
||||
"@jest/source-map": "^27.0.6",
|
||||
"@jest/test-result": "^27.0.6",
|
||||
"@jest/transform": "^27.0.6",
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/test-result": "^27.1.0",
|
||||
"@jest/transform": "^27.1.0",
|
||||
"@jest/types": "^27.1.0",
|
||||
"@types/yargs": "^16.0.0",
|
||||
"chalk": "^4.0.0",
|
||||
"cjs-module-lexer": "^1.0.0",
|
||||
"collect-v8-coverage": "^1.0.0",
|
||||
"execa": "^5.0.0",
|
||||
"exit": "^0.1.2",
|
||||
"glob": "^7.1.3",
|
||||
"graceful-fs": "^4.2.4",
|
||||
"jest-haste-map": "^27.0.6",
|
||||
"jest-message-util": "^27.0.6",
|
||||
"jest-mock": "^27.0.6",
|
||||
"jest-haste-map": "^27.1.0",
|
||||
"jest-message-util": "^27.1.0",
|
||||
"jest-mock": "^27.1.0",
|
||||
"jest-regex-util": "^27.0.6",
|
||||
"jest-resolve": "^27.0.6",
|
||||
"jest-snapshot": "^27.0.6",
|
||||
"jest-util": "^27.0.6",
|
||||
"jest-validate": "^27.0.6",
|
||||
"jest-resolve": "^27.1.0",
|
||||
"jest-snapshot": "^27.1.0",
|
||||
"jest-util": "^27.1.0",
|
||||
"jest-validate": "^27.1.0",
|
||||
"slash": "^3.0.0",
|
||||
"strip-bom": "^4.0.0",
|
||||
"yargs": "^16.0.3"
|
||||
@@ -14464,9 +14422,9 @@
|
||||
}
|
||||
},
|
||||
"jest-snapshot": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.0.6.tgz",
|
||||
"integrity": "sha512-NTHaz8He+ATUagUgE7C/UtFcRoHqR2Gc+KDfhQIyx+VFgwbeEMjeP+ILpUTLosZn/ZtbNdCF5LkVnN/l+V751A==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.1.0.tgz",
|
||||
"integrity": "sha512-eaeUBoEjuuRwmiRI51oTldUsKOohB1F6fPqWKKILuDi/CStxzp2IWekVUXbuHHoz5ik33ioJhshiHpgPFbYgcA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/core": "^7.7.2",
|
||||
@@ -14475,33 +14433,33 @@
|
||||
"@babel/plugin-syntax-typescript": "^7.7.2",
|
||||
"@babel/traverse": "^7.7.2",
|
||||
"@babel/types": "^7.0.0",
|
||||
"@jest/transform": "^27.0.6",
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/transform": "^27.1.0",
|
||||
"@jest/types": "^27.1.0",
|
||||
"@types/babel__traverse": "^7.0.4",
|
||||
"@types/prettier": "^2.1.5",
|
||||
"babel-preset-current-node-syntax": "^1.0.0",
|
||||
"chalk": "^4.0.0",
|
||||
"expect": "^27.0.6",
|
||||
"expect": "^27.1.0",
|
||||
"graceful-fs": "^4.2.4",
|
||||
"jest-diff": "^27.0.6",
|
||||
"jest-diff": "^27.1.0",
|
||||
"jest-get-type": "^27.0.6",
|
||||
"jest-haste-map": "^27.0.6",
|
||||
"jest-matcher-utils": "^27.0.6",
|
||||
"jest-message-util": "^27.0.6",
|
||||
"jest-resolve": "^27.0.6",
|
||||
"jest-util": "^27.0.6",
|
||||
"jest-haste-map": "^27.1.0",
|
||||
"jest-matcher-utils": "^27.1.0",
|
||||
"jest-message-util": "^27.1.0",
|
||||
"jest-resolve": "^27.1.0",
|
||||
"jest-util": "^27.1.0",
|
||||
"natural-compare": "^1.4.0",
|
||||
"pretty-format": "^27.0.6",
|
||||
"pretty-format": "^27.1.0",
|
||||
"semver": "^7.3.2"
|
||||
}
|
||||
},
|
||||
"jest-util": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.0.6.tgz",
|
||||
"integrity": "sha512-1JjlaIh+C65H/F7D11GNkGDDZtDfMEM8EBXsvd+l/cxtgQ6QhxuloOaiayt89DxUvDarbVhqI98HhgrM1yliFQ==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.1.0.tgz",
|
||||
"integrity": "sha512-edSLD2OneYDKC6gZM1yc+wY/877s/fuJNoM1k3sOEpzFyeptSmke3SLnk1dDHk9CgTA+58mnfx3ew3J11Kes/w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/types": "^27.1.0",
|
||||
"@types/node": "*",
|
||||
"chalk": "^4.0.0",
|
||||
"graceful-fs": "^4.2.4",
|
||||
@@ -14510,38 +14468,38 @@
|
||||
}
|
||||
},
|
||||
"jest-validate": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.0.6.tgz",
|
||||
"integrity": "sha512-yhZZOaMH3Zg6DC83n60pLmdU1DQE46DW+KLozPiPbSbPhlXXaiUTDlhHQhHFpaqIFRrInko1FHXjTRpjWRuWfA==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.1.0.tgz",
|
||||
"integrity": "sha512-QiJ+4XuSuMsfPi9zvdO//IrSRSlG6ybJhOpuqYSsuuaABaNT84h0IoD6vvQhThBOKT+DIKvl5sTM0l6is9+SRA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/types": "^27.1.0",
|
||||
"camelcase": "^6.2.0",
|
||||
"chalk": "^4.0.0",
|
||||
"jest-get-type": "^27.0.6",
|
||||
"leven": "^3.1.0",
|
||||
"pretty-format": "^27.0.6"
|
||||
"pretty-format": "^27.1.0"
|
||||
}
|
||||
},
|
||||
"jest-watcher": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.0.6.tgz",
|
||||
"integrity": "sha512-/jIoKBhAP00/iMGnTwUBLgvxkn7vsOweDrOTSPzc7X9uOyUtJIDthQBTI1EXz90bdkrxorUZVhJwiB69gcHtYQ==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.1.0.tgz",
|
||||
"integrity": "sha512-ivaWTrA46aHWdgPDgPypSHiNQjyKnLBpUIHeBaGg11U+pDzZpkffGlcB1l1a014phmG0mHgkOHtOgiqJQM6yKQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/test-result": "^27.0.6",
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/test-result": "^27.1.0",
|
||||
"@jest/types": "^27.1.0",
|
||||
"@types/node": "*",
|
||||
"ansi-escapes": "^4.2.1",
|
||||
"chalk": "^4.0.0",
|
||||
"jest-util": "^27.0.6",
|
||||
"jest-util": "^27.1.0",
|
||||
"string-length": "^4.0.1"
|
||||
}
|
||||
},
|
||||
"jest-worker": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.0.6.tgz",
|
||||
"integrity": "sha512-qupxcj/dRuA3xHPMUd40gr2EaAurFbkwzOh7wfPaeE9id7hyjURRQoqNfHifHK3XjJU6YJJUQKILGUnwGPEOCA==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.1.0.tgz",
|
||||
"integrity": "sha512-mO4PHb2QWLn9yRXGp7rkvXLAYuxwhq1ZYUo0LoDhg8wqvv4QizP1ZWEJOeolgbEgAWZLIEU0wsku8J+lGWfBhg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*",
|
||||
@@ -14560,50 +14518,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"jsdom": {
|
||||
"version": "16.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz",
|
||||
"integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"abab": "^2.0.5",
|
||||
"acorn": "^8.2.4",
|
||||
"acorn-globals": "^6.0.0",
|
||||
"cssom": "^0.4.4",
|
||||
"cssstyle": "^2.3.0",
|
||||
"data-urls": "^2.0.0",
|
||||
"decimal.js": "^10.2.1",
|
||||
"domexception": "^2.0.1",
|
||||
"escodegen": "^2.0.0",
|
||||
"form-data": "^3.0.0",
|
||||
"html-encoding-sniffer": "^2.0.1",
|
||||
"http-proxy-agent": "^4.0.1",
|
||||
"https-proxy-agent": "^5.0.0",
|
||||
"is-potential-custom-element-name": "^1.0.1",
|
||||
"nwsapi": "^2.2.0",
|
||||
"parse5": "6.0.1",
|
||||
"saxes": "^5.0.1",
|
||||
"symbol-tree": "^3.2.4",
|
||||
"tough-cookie": "^4.0.0",
|
||||
"w3c-hr-time": "^1.0.2",
|
||||
"w3c-xmlserializer": "^2.0.0",
|
||||
"webidl-conversions": "^6.1.0",
|
||||
"whatwg-encoding": "^1.0.5",
|
||||
"whatwg-mimetype": "^2.3.0",
|
||||
"whatwg-url": "^8.5.0",
|
||||
"ws": "^7.4.6",
|
||||
"xml-name-validator": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"micromatch": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
|
||||
@@ -14630,12 +14544,12 @@
|
||||
"dev": true
|
||||
},
|
||||
"pretty-format": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.6.tgz",
|
||||
"integrity": "sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.1.0.tgz",
|
||||
"integrity": "sha512-4aGaud3w3rxAO6OXmK3fwBFQ0bctIOG3/if+jYEFGNGIs0EvuidQm3bZ9mlP2/t9epLNC/12czabfy7TZNSwVA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/types": "^27.1.0",
|
||||
"ansi-regex": "^5.0.0",
|
||||
"ansi-styles": "^5.0.0",
|
||||
"react-is": "^17.0.1"
|
||||
@@ -14694,30 +14608,12 @@
|
||||
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
|
||||
"dev": true
|
||||
},
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"strip-bom": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
|
||||
"integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
|
||||
"dev": true
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-flag": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"throat": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz",
|
||||
@@ -14760,56 +14656,6 @@
|
||||
"requires": {
|
||||
"isexe": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"ws": {
|
||||
"version": "7.5.3",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz",
|
||||
"integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==",
|
||||
"dev": true
|
||||
},
|
||||
"y18n": {
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
|
||||
"dev": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||
"dev": true
|
||||
},
|
||||
"yargs": {
|
||||
"version": "16.2.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
|
||||
"integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cliui": "^7.0.2",
|
||||
"escalade": "^3.1.1",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"require-directory": "^2.1.1",
|
||||
"string-width": "^4.2.0",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^20.2.2"
|
||||
}
|
||||
},
|
||||
"yargs-parser": {
|
||||
"version": "20.2.9",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
|
||||
"integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -14921,81 +14767,81 @@
|
||||
}
|
||||
},
|
||||
"jest-circus": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.0.6.tgz",
|
||||
"integrity": "sha512-OJlsz6BBeX9qR+7O9lXefWoc2m9ZqcZ5Ohlzz0pTEAG4xMiZUJoacY8f4YDHxgk0oKYxj277AfOk9w6hZYvi1Q==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.1.0.tgz",
|
||||
"integrity": "sha512-6FWtHs3nZyZlMBhRf1wvAC5CirnflbGJAY1xssSAnERLiiXQRH+wY2ptBVtXjX4gz4AA2EwRV57b038LmifRbA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/environment": "^27.0.6",
|
||||
"@jest/test-result": "^27.0.6",
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/environment": "^27.1.0",
|
||||
"@jest/test-result": "^27.1.0",
|
||||
"@jest/types": "^27.1.0",
|
||||
"@types/node": "*",
|
||||
"chalk": "^4.0.0",
|
||||
"co": "^4.6.0",
|
||||
"dedent": "^0.7.0",
|
||||
"expect": "^27.0.6",
|
||||
"expect": "^27.1.0",
|
||||
"is-generator-fn": "^2.0.0",
|
||||
"jest-each": "^27.0.6",
|
||||
"jest-matcher-utils": "^27.0.6",
|
||||
"jest-message-util": "^27.0.6",
|
||||
"jest-runtime": "^27.0.6",
|
||||
"jest-snapshot": "^27.0.6",
|
||||
"jest-util": "^27.0.6",
|
||||
"pretty-format": "^27.0.6",
|
||||
"jest-each": "^27.1.0",
|
||||
"jest-matcher-utils": "^27.1.0",
|
||||
"jest-message-util": "^27.1.0",
|
||||
"jest-runtime": "^27.1.0",
|
||||
"jest-snapshot": "^27.1.0",
|
||||
"jest-util": "^27.1.0",
|
||||
"pretty-format": "^27.1.0",
|
||||
"slash": "^3.0.0",
|
||||
"stack-utils": "^2.0.3",
|
||||
"throat": "^6.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@jest/console": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@jest/console/-/console-27.0.6.tgz",
|
||||
"integrity": "sha512-fMlIBocSHPZ3JxgWiDNW/KPj6s+YRd0hicb33IrmelCcjXo/pXPwvuiKFmZz+XuqI/1u7nbUK10zSsWL/1aegg==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/console/-/console-27.1.0.tgz",
|
||||
"integrity": "sha512-+Vl+xmLwAXLNlqT61gmHEixeRbS4L8MUzAjtpBCOPWH+izNI/dR16IeXjkXJdRtIVWVSf9DO1gdp67B1XorZhQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/types": "^27.1.0",
|
||||
"@types/node": "*",
|
||||
"chalk": "^4.0.0",
|
||||
"jest-message-util": "^27.0.6",
|
||||
"jest-util": "^27.0.6",
|
||||
"jest-message-util": "^27.1.0",
|
||||
"jest-util": "^27.1.0",
|
||||
"slash": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"@jest/environment": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.0.6.tgz",
|
||||
"integrity": "sha512-4XywtdhwZwCpPJ/qfAkqExRsERW+UaoSRStSHCCiQTUpoYdLukj+YJbQSFrZjhlUDRZeNiU9SFH0u7iNimdiIg==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.1.0.tgz",
|
||||
"integrity": "sha512-wRp50aAMY2w1U2jP1G32d6FUVBNYqmk8WaGkiIEisU48qyDV0WPtw3IBLnl7orBeggveommAkuijY+RzVnNDOQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/fake-timers": "^27.0.6",
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/fake-timers": "^27.1.0",
|
||||
"@jest/types": "^27.1.0",
|
||||
"@types/node": "*",
|
||||
"jest-mock": "^27.0.6"
|
||||
"jest-mock": "^27.1.0"
|
||||
}
|
||||
},
|
||||
"@jest/fake-timers": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.0.6.tgz",
|
||||
"integrity": "sha512-sqd+xTWtZ94l3yWDKnRTdvTeZ+A/V7SSKrxsrOKSqdyddb9CeNRF8fbhAU0D7ZJBpTTW2nbp6MftmKJDZfW2LQ==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.1.0.tgz",
|
||||
"integrity": "sha512-22Zyn8il8DzpS+30jJNVbTlm7vAtnfy1aYvNeOEHloMlGy1PCYLHa4PWlSws0hvNsMM5bON6GISjkLoQUV3oMA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/types": "^27.1.0",
|
||||
"@sinonjs/fake-timers": "^7.0.2",
|
||||
"@types/node": "*",
|
||||
"jest-message-util": "^27.0.6",
|
||||
"jest-mock": "^27.0.6",
|
||||
"jest-util": "^27.0.6"
|
||||
"jest-message-util": "^27.1.0",
|
||||
"jest-mock": "^27.1.0",
|
||||
"jest-util": "^27.1.0"
|
||||
}
|
||||
},
|
||||
"@jest/globals": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.0.6.tgz",
|
||||
"integrity": "sha512-DdTGCP606rh9bjkdQ7VvChV18iS7q0IMJVP1piwTWyWskol4iqcVwthZmoJEf7obE1nc34OpIyoVGPeqLC+ryw==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.1.0.tgz",
|
||||
"integrity": "sha512-73vLV4aNHAlAgjk0/QcSIzzCZSqVIPbmFROJJv9D3QUR7BI4f517gVdJpSrCHxuRH3VZFhe0yGG/tmttlMll9g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/environment": "^27.0.6",
|
||||
"@jest/types": "^27.0.6",
|
||||
"expect": "^27.0.6"
|
||||
"@jest/environment": "^27.1.0",
|
||||
"@jest/types": "^27.1.0",
|
||||
"expect": "^27.1.0"
|
||||
}
|
||||
},
|
||||
"@jest/source-map": {
|
||||
@@ -15010,33 +14856,33 @@
|
||||
}
|
||||
},
|
||||
"@jest/test-result": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.0.6.tgz",
|
||||
"integrity": "sha512-ja/pBOMTufjX4JLEauLxE3LQBPaI2YjGFtXexRAjt1I/MbfNlMx0sytSX3tn5hSLzQsR3Qy2rd0hc1BWojtj9w==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.1.0.tgz",
|
||||
"integrity": "sha512-Aoz00gpDL528ODLghat3QSy6UBTD5EmmpjrhZZMK/v1Q2/rRRqTGnFxHuEkrD4z/Py96ZdOHxIWkkCKRpmnE1A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/console": "^27.0.6",
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/console": "^27.1.0",
|
||||
"@jest/types": "^27.1.0",
|
||||
"@types/istanbul-lib-coverage": "^2.0.0",
|
||||
"collect-v8-coverage": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"@jest/transform": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.0.6.tgz",
|
||||
"integrity": "sha512-rj5Dw+mtIcntAUnMlW/Vju5mr73u8yg+irnHwzgtgoeI6cCPOvUwQ0D1uQtc/APmWgvRweEb1g05pkUpxH3iCA==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.1.0.tgz",
|
||||
"integrity": "sha512-ZRGCA2ZEVJ00ubrhkTG87kyLbN6n55g1Ilq0X9nJb5bX3MhMp3O6M7KG+LvYu+nZRqG5cXsQnJEdZbdpTAV8pQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/core": "^7.1.0",
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/types": "^27.1.0",
|
||||
"babel-plugin-istanbul": "^6.0.0",
|
||||
"chalk": "^4.0.0",
|
||||
"convert-source-map": "^1.4.0",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
"graceful-fs": "^4.2.4",
|
||||
"jest-haste-map": "^27.0.6",
|
||||
"jest-haste-map": "^27.1.0",
|
||||
"jest-regex-util": "^27.0.6",
|
||||
"jest-util": "^27.0.6",
|
||||
"jest-util": "^27.1.0",
|
||||
"micromatch": "^4.0.4",
|
||||
"pirates": "^4.0.1",
|
||||
"slash": "^3.0.0",
|
||||
@@ -15045,9 +14891,9 @@
|
||||
}
|
||||
},
|
||||
"@jest/types": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
|
||||
"integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/types/-/types-27.1.0.tgz",
|
||||
"integrity": "sha512-pRP5cLIzN7I7Vp6mHKRSaZD7YpBTK7hawx5si8trMKqk4+WOdK8NEKOTO2G8PKWD1HbKMVckVB6/XHh/olhf2g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/istanbul-lib-coverage": "^2.0.0",
|
||||
@@ -15125,17 +14971,6 @@
|
||||
"integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==",
|
||||
"dev": true
|
||||
},
|
||||
"cliui": {
|
||||
"version": "7.0.4",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
|
||||
"integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"wrap-ansi": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
@@ -15151,23 +14986,51 @@
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true
|
||||
},
|
||||
"cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"path-key": "^3.1.0",
|
||||
"shebang-command": "^2.0.0",
|
||||
"which": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"diff-sequences": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz",
|
||||
"integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==",
|
||||
"dev": true
|
||||
},
|
||||
"expect": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/expect/-/expect-27.0.6.tgz",
|
||||
"integrity": "sha512-psNLt8j2kwg42jGBDSfAlU49CEZxejN1f1PlANWDZqIhBOVU/c2Pm888FcjWJzFewhIsNWfZJeLjUjtKGiPuSw==",
|
||||
"execa": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
|
||||
"integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/types": "^27.0.6",
|
||||
"cross-spawn": "^7.0.3",
|
||||
"get-stream": "^6.0.0",
|
||||
"human-signals": "^2.1.0",
|
||||
"is-stream": "^2.0.0",
|
||||
"merge-stream": "^2.0.0",
|
||||
"npm-run-path": "^4.0.1",
|
||||
"onetime": "^5.1.2",
|
||||
"signal-exit": "^3.0.3",
|
||||
"strip-final-newline": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"expect": {
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/expect/-/expect-27.1.0.tgz",
|
||||
"integrity": "sha512-9kJngV5hOJgkFil4F/uXm3hVBubUK2nERVfvqNNwxxuW8ZOUwSTTSysgfzckYtv/LBzj/LJXbiAF7okHCXgdug==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/types": "^27.1.0",
|
||||
"ansi-styles": "^5.0.0",
|
||||
"jest-get-type": "^27.0.6",
|
||||
"jest-matcher-utils": "^27.0.6",
|
||||
"jest-message-util": "^27.0.6",
|
||||
"jest-matcher-utils": "^27.1.0",
|
||||
"jest-message-util": "^27.1.0",
|
||||
"jest-regex-util": "^27.0.6"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -15195,6 +15058,12 @@
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"get-stream": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
|
||||
"integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
|
||||
"dev": true
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
@@ -15216,29 +15085,35 @@
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||
"dev": true
|
||||
},
|
||||
"is-stream": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
|
||||
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
|
||||
"dev": true
|
||||
},
|
||||
"jest-diff": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.0.6.tgz",
|
||||
"integrity": "sha512-Z1mqgkTCSYaFgwTlP/NUiRzdqgxmmhzHY1Tq17zL94morOHfHu3K4bgSgl+CR4GLhpV8VxkuOYuIWnQ9LnFqmg==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.1.0.tgz",
|
||||
"integrity": "sha512-rjfopEYl58g/SZTsQFmspBODvMSytL16I+cirnScWTLkQVXYVZfxm78DFfdIIXc05RCYuGjxJqrdyG4PIFzcJg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "^4.0.0",
|
||||
"diff-sequences": "^27.0.6",
|
||||
"jest-get-type": "^27.0.6",
|
||||
"pretty-format": "^27.0.6"
|
||||
"pretty-format": "^27.1.0"
|
||||
}
|
||||
},
|
||||
"jest-each": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.0.6.tgz",
|
||||
"integrity": "sha512-m6yKcV3bkSWrUIjxkE9OC0mhBZZdhovIW5ergBYirqnkLXkyEn3oUUF/QZgyecA1cF1QFyTE8bRRl8Tfg1pfLA==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.1.0.tgz",
|
||||
"integrity": "sha512-K/cNvQlmDqQMRHF8CaQ0XPzCfjP5HMJc2bIJglrIqI9fjwpNqITle63IWE+wq4p+3v+iBgh7Wq0IdGpLx5xjDg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/types": "^27.1.0",
|
||||
"chalk": "^4.0.0",
|
||||
"jest-get-type": "^27.0.6",
|
||||
"jest-util": "^27.0.6",
|
||||
"pretty-format": "^27.0.6"
|
||||
"jest-util": "^27.1.0",
|
||||
"pretty-format": "^27.1.0"
|
||||
}
|
||||
},
|
||||
"jest-get-type": {
|
||||
@@ -15248,12 +15123,12 @@
|
||||
"dev": true
|
||||
},
|
||||
"jest-haste-map": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.0.6.tgz",
|
||||
"integrity": "sha512-4ldjPXX9h8doB2JlRzg9oAZ2p6/GpQUNAeiYXqcpmrKbP0Qev0wdZlxSMOmz8mPOEnt4h6qIzXFLDi8RScX/1w==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.1.0.tgz",
|
||||
"integrity": "sha512-7mz6LopSe+eA6cTFMf10OfLLqRoIPvmMyz5/OnSXnHO7hB0aDP1iIeLWCXzAcYU5eIJVpHr12Bk9yyq2fTW9vg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/types": "^27.1.0",
|
||||
"@types/graceful-fs": "^4.1.2",
|
||||
"@types/node": "*",
|
||||
"anymatch": "^3.0.3",
|
||||
@@ -15262,48 +15137,48 @@
|
||||
"graceful-fs": "^4.2.4",
|
||||
"jest-regex-util": "^27.0.6",
|
||||
"jest-serializer": "^27.0.6",
|
||||
"jest-util": "^27.0.6",
|
||||
"jest-worker": "^27.0.6",
|
||||
"jest-util": "^27.1.0",
|
||||
"jest-worker": "^27.1.0",
|
||||
"micromatch": "^4.0.4",
|
||||
"walker": "^1.0.7"
|
||||
}
|
||||
},
|
||||
"jest-matcher-utils": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.0.6.tgz",
|
||||
"integrity": "sha512-OFgF2VCQx9vdPSYTHWJ9MzFCehs20TsyFi6bIHbk5V1u52zJOnvF0Y/65z3GLZHKRuTgVPY4Z6LVePNahaQ+tA==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.1.0.tgz",
|
||||
"integrity": "sha512-VmAudus2P6Yt/JVBRdTPFhUzlIN8DYJd+et5Rd9QDsO/Z82Z4iwGjo43U8Z+PTiz8CBvKvlb6Fh3oKy39hykkQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "^4.0.0",
|
||||
"jest-diff": "^27.0.6",
|
||||
"jest-diff": "^27.1.0",
|
||||
"jest-get-type": "^27.0.6",
|
||||
"pretty-format": "^27.0.6"
|
||||
"pretty-format": "^27.1.0"
|
||||
}
|
||||
},
|
||||
"jest-message-util": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.0.6.tgz",
|
||||
"integrity": "sha512-rBxIs2XK7rGy+zGxgi+UJKP6WqQ+KrBbD1YMj517HYN3v2BG66t3Xan3FWqYHKZwjdB700KiAJ+iES9a0M+ixw==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.1.0.tgz",
|
||||
"integrity": "sha512-Eck8NFnJ5Sg36R9XguD65cf2D5+McC+NF5GIdEninoabcuoOfWrID5qJhufq5FB0DRKoiyxB61hS7MKoMD0trQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.12.13",
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/types": "^27.1.0",
|
||||
"@types/stack-utils": "^2.0.0",
|
||||
"chalk": "^4.0.0",
|
||||
"graceful-fs": "^4.2.4",
|
||||
"micromatch": "^4.0.4",
|
||||
"pretty-format": "^27.0.6",
|
||||
"pretty-format": "^27.1.0",
|
||||
"slash": "^3.0.0",
|
||||
"stack-utils": "^2.0.3"
|
||||
}
|
||||
},
|
||||
"jest-mock": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.0.6.tgz",
|
||||
"integrity": "sha512-lzBETUoK8cSxts2NYXSBWT+EJNzmUVtVVwS1sU9GwE1DLCfGsngg+ZVSIe0yd0ZSm+y791esiuo+WSwpXJQ5Bw==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.1.0.tgz",
|
||||
"integrity": "sha512-iT3/Yhu7DwAg/0HvvLCqLvrTKTRMyJlrrfJYWzuLSf9RCAxBoIXN3HoymZxMnYsC3eD8ewGbUa9jUknwBenx2w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/types": "^27.1.0",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
@@ -15314,51 +15189,53 @@
|
||||
"dev": true
|
||||
},
|
||||
"jest-resolve": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.0.6.tgz",
|
||||
"integrity": "sha512-yKmIgw2LgTh7uAJtzv8UFHGF7Dm7XfvOe/LQ3Txv101fLM8cx2h1QVwtSJ51Q/SCxpIiKfVn6G2jYYMDNHZteA==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.1.0.tgz",
|
||||
"integrity": "sha512-TXvzrLyPg0vLOwcWX38ZGYeEztSEmW+cQQKqc4HKDUwun31wsBXwotRlUz4/AYU/Fq4GhbMd/ileIWZEtcdmIA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/types": "^27.1.0",
|
||||
"chalk": "^4.0.0",
|
||||
"escalade": "^3.1.1",
|
||||
"graceful-fs": "^4.2.4",
|
||||
"jest-haste-map": "^27.1.0",
|
||||
"jest-pnp-resolver": "^1.2.2",
|
||||
"jest-util": "^27.0.6",
|
||||
"jest-validate": "^27.0.6",
|
||||
"jest-util": "^27.1.0",
|
||||
"jest-validate": "^27.1.0",
|
||||
"resolve": "^1.20.0",
|
||||
"slash": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"jest-runtime": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.0.6.tgz",
|
||||
"integrity": "sha512-BhvHLRVfKibYyqqEFkybsznKwhrsu7AWx2F3y9G9L95VSIN3/ZZ9vBpm/XCS2bS+BWz3sSeNGLzI3TVQ0uL85Q==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.1.0.tgz",
|
||||
"integrity": "sha512-okiR2cpGjY0RkWmUGGado6ETpFOi9oG3yV0CioYdoktkVxy5Hv0WRLWnJFuArSYS8cHMCNcceUUMGiIfgxCO9A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/console": "^27.0.6",
|
||||
"@jest/environment": "^27.0.6",
|
||||
"@jest/fake-timers": "^27.0.6",
|
||||
"@jest/globals": "^27.0.6",
|
||||
"@jest/console": "^27.1.0",
|
||||
"@jest/environment": "^27.1.0",
|
||||
"@jest/fake-timers": "^27.1.0",
|
||||
"@jest/globals": "^27.1.0",
|
||||
"@jest/source-map": "^27.0.6",
|
||||
"@jest/test-result": "^27.0.6",
|
||||
"@jest/transform": "^27.0.6",
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/test-result": "^27.1.0",
|
||||
"@jest/transform": "^27.1.0",
|
||||
"@jest/types": "^27.1.0",
|
||||
"@types/yargs": "^16.0.0",
|
||||
"chalk": "^4.0.0",
|
||||
"cjs-module-lexer": "^1.0.0",
|
||||
"collect-v8-coverage": "^1.0.0",
|
||||
"execa": "^5.0.0",
|
||||
"exit": "^0.1.2",
|
||||
"glob": "^7.1.3",
|
||||
"graceful-fs": "^4.2.4",
|
||||
"jest-haste-map": "^27.0.6",
|
||||
"jest-message-util": "^27.0.6",
|
||||
"jest-mock": "^27.0.6",
|
||||
"jest-haste-map": "^27.1.0",
|
||||
"jest-message-util": "^27.1.0",
|
||||
"jest-mock": "^27.1.0",
|
||||
"jest-regex-util": "^27.0.6",
|
||||
"jest-resolve": "^27.0.6",
|
||||
"jest-snapshot": "^27.0.6",
|
||||
"jest-util": "^27.0.6",
|
||||
"jest-validate": "^27.0.6",
|
||||
"jest-resolve": "^27.1.0",
|
||||
"jest-snapshot": "^27.1.0",
|
||||
"jest-util": "^27.1.0",
|
||||
"jest-validate": "^27.1.0",
|
||||
"slash": "^3.0.0",
|
||||
"strip-bom": "^4.0.0",
|
||||
"yargs": "^16.0.3"
|
||||
@@ -15375,9 +15252,9 @@
|
||||
}
|
||||
},
|
||||
"jest-snapshot": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.0.6.tgz",
|
||||
"integrity": "sha512-NTHaz8He+ATUagUgE7C/UtFcRoHqR2Gc+KDfhQIyx+VFgwbeEMjeP+ILpUTLosZn/ZtbNdCF5LkVnN/l+V751A==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.1.0.tgz",
|
||||
"integrity": "sha512-eaeUBoEjuuRwmiRI51oTldUsKOohB1F6fPqWKKILuDi/CStxzp2IWekVUXbuHHoz5ik33ioJhshiHpgPFbYgcA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/core": "^7.7.2",
|
||||
@@ -15386,33 +15263,33 @@
|
||||
"@babel/plugin-syntax-typescript": "^7.7.2",
|
||||
"@babel/traverse": "^7.7.2",
|
||||
"@babel/types": "^7.0.0",
|
||||
"@jest/transform": "^27.0.6",
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/transform": "^27.1.0",
|
||||
"@jest/types": "^27.1.0",
|
||||
"@types/babel__traverse": "^7.0.4",
|
||||
"@types/prettier": "^2.1.5",
|
||||
"babel-preset-current-node-syntax": "^1.0.0",
|
||||
"chalk": "^4.0.0",
|
||||
"expect": "^27.0.6",
|
||||
"expect": "^27.1.0",
|
||||
"graceful-fs": "^4.2.4",
|
||||
"jest-diff": "^27.0.6",
|
||||
"jest-diff": "^27.1.0",
|
||||
"jest-get-type": "^27.0.6",
|
||||
"jest-haste-map": "^27.0.6",
|
||||
"jest-matcher-utils": "^27.0.6",
|
||||
"jest-message-util": "^27.0.6",
|
||||
"jest-resolve": "^27.0.6",
|
||||
"jest-util": "^27.0.6",
|
||||
"jest-haste-map": "^27.1.0",
|
||||
"jest-matcher-utils": "^27.1.0",
|
||||
"jest-message-util": "^27.1.0",
|
||||
"jest-resolve": "^27.1.0",
|
||||
"jest-util": "^27.1.0",
|
||||
"natural-compare": "^1.4.0",
|
||||
"pretty-format": "^27.0.6",
|
||||
"pretty-format": "^27.1.0",
|
||||
"semver": "^7.3.2"
|
||||
}
|
||||
},
|
||||
"jest-util": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.0.6.tgz",
|
||||
"integrity": "sha512-1JjlaIh+C65H/F7D11GNkGDDZtDfMEM8EBXsvd+l/cxtgQ6QhxuloOaiayt89DxUvDarbVhqI98HhgrM1yliFQ==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.1.0.tgz",
|
||||
"integrity": "sha512-edSLD2OneYDKC6gZM1yc+wY/877s/fuJNoM1k3sOEpzFyeptSmke3SLnk1dDHk9CgTA+58mnfx3ew3J11Kes/w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/types": "^27.1.0",
|
||||
"@types/node": "*",
|
||||
"chalk": "^4.0.0",
|
||||
"graceful-fs": "^4.2.4",
|
||||
@@ -15421,23 +15298,23 @@
|
||||
}
|
||||
},
|
||||
"jest-validate": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.0.6.tgz",
|
||||
"integrity": "sha512-yhZZOaMH3Zg6DC83n60pLmdU1DQE46DW+KLozPiPbSbPhlXXaiUTDlhHQhHFpaqIFRrInko1FHXjTRpjWRuWfA==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.1.0.tgz",
|
||||
"integrity": "sha512-QiJ+4XuSuMsfPi9zvdO//IrSRSlG6ybJhOpuqYSsuuaABaNT84h0IoD6vvQhThBOKT+DIKvl5sTM0l6is9+SRA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/types": "^27.0.6",
|
||||
"@jest/types": "^27.1.0",
|
||||
"camelcase": "^6.2.0",
|
||||
"chalk": "^4.0.0",
|
||||
"jest-get-type": "^27.0.6",
|
||||
"leven": "^3.1.0",
|
||||
"pretty-format": "^27.0.6"
|
||||
"pretty-format": "^27.1.0"
|
||||
}
|
||||
},
|
||||
"jest-worker": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.0.6.tgz",
|
||||
"integrity": "sha512-qupxcj/dRuA3xHPMUd40gr2EaAurFbkwzOh7wfPaeE9id7hyjURRQoqNfHifHK3XjJU6YJJUQKILGUnwGPEOCA==",
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.1.0.tgz",
|
||||
"integrity": "sha512-mO4PHb2QWLn9yRXGp7rkvXLAYuxwhq1ZYUo0LoDhg8wqvv4QizP1ZWEJOeolgbEgAWZLIEU0wsku8J+lGWfBhg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*",
|
||||
@@ -15456,15 +15333,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"micromatch": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
|
||||
@@ -15475,13 +15343,28 @@
|
||||
"picomatch": "^2.2.3"
|
||||
}
|
||||
},
|
||||
"pretty-format": {
|
||||
"version": "27.0.6",
|
||||
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.6.tgz",
|
||||
"integrity": "sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ==",
|
||||
"npm-run-path": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
|
||||
"integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/types": "^27.0.6",
|
||||
"path-key": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"path-key": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
||||
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
|
||||
"dev": true
|
||||
},
|
||||
"pretty-format": {
|
||||
"version": "27.1.0",
|
||||
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.1.0.tgz",
|
||||
"integrity": "sha512-4aGaud3w3rxAO6OXmK3fwBFQ0bctIOG3/if+jYEFGNGIs0EvuidQm3bZ9mlP2/t9epLNC/12czabfy7TZNSwVA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/types": "^27.1.0",
|
||||
"ansi-regex": "^5.0.0",
|
||||
"ansi-styles": "^5.0.0",
|
||||
"react-is": "^17.0.1"
|
||||
@@ -15510,36 +15393,33 @@
|
||||
"lru-cache": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"shebang-command": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"shebang-regex": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"shebang-regex": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
|
||||
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
|
||||
"dev": true
|
||||
},
|
||||
"slash": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
|
||||
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
|
||||
"dev": true
|
||||
},
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"strip-bom": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
|
||||
"integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
|
||||
"dev": true
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-flag": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"throat": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz",
|
||||
@@ -15555,49 +15435,14 @@
|
||||
"is-number": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
"isexe": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"y18n": {
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
|
||||
"dev": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||
"dev": true
|
||||
},
|
||||
"yargs": {
|
||||
"version": "16.2.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
|
||||
"integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cliui": "^7.0.2",
|
||||
"escalade": "^3.1.1",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"require-directory": "^2.1.1",
|
||||
"string-width": "^4.2.0",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^20.2.2"
|
||||
}
|
||||
},
|
||||
"yargs-parser": {
|
||||
"version": "20.2.9",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
|
||||
"integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -16420,6 +16265,12 @@
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"camelcase": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
|
||||
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
|
||||
"dev": true
|
||||
},
|
||||
"chalk": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
@@ -16430,6 +16281,17 @@
|
||||
"supports-color": "^7.1.0"
|
||||
}
|
||||
},
|
||||
"cliui": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
|
||||
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"wrap-ansi": "^6.2.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
@@ -16456,6 +16318,52 @@
|
||||
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
|
||||
"integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
|
||||
"dev": true
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
|
||||
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"y18n": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
|
||||
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
|
||||
"dev": true
|
||||
},
|
||||
"yargs": {
|
||||
"version": "15.4.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
|
||||
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cliui": "^6.0.0",
|
||||
"decamelize": "^1.2.0",
|
||||
"find-up": "^4.1.0",
|
||||
"get-caller-file": "^2.0.1",
|
||||
"require-directory": "^2.1.1",
|
||||
"require-main-filename": "^2.0.0",
|
||||
"set-blocking": "^2.0.0",
|
||||
"string-width": "^4.2.0",
|
||||
"which-module": "^2.0.0",
|
||||
"y18n": "^4.0.0",
|
||||
"yargs-parser": "^18.1.2"
|
||||
}
|
||||
},
|
||||
"yargs-parser": {
|
||||
"version": "18.1.3",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
|
||||
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -16922,16 +16830,11 @@
|
||||
"json-buffer": "3.0.0"
|
||||
}
|
||||
},
|
||||
"killable": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
|
||||
"integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==",
|
||||
"dev": true
|
||||
},
|
||||
"kind-of": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
|
||||
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="
|
||||
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
|
||||
"dev": true
|
||||
},
|
||||
"kleur": {
|
||||
"version": "3.0.3",
|
||||
@@ -17375,11 +17278,6 @@
|
||||
"requires": {
|
||||
"strict-uri-encode": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"strict-uri-encode": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
|
||||
"integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -17427,7 +17325,8 @@
|
||||
"map-cache": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
|
||||
"integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8="
|
||||
"integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
|
||||
"dev": true
|
||||
},
|
||||
"map-obj": {
|
||||
"version": "1.0.1",
|
||||
@@ -17440,6 +17339,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
|
||||
"integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"object-visit": "^1.0.0"
|
||||
}
|
||||
@@ -17672,6 +17572,7 @@
|
||||
"version": "3.1.10",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
|
||||
"integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"arr-diff": "^4.0.0",
|
||||
"array-unique": "^0.3.2",
|
||||
@@ -17774,33 +17675,27 @@
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.9.0",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz",
|
||||
"integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==",
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.5.tgz",
|
||||
"integrity": "sha512-+8NzxD82XQoNKNrl1d/FSi+X8wAEWR+sbYAfIvub4Nz0d22plFG72CEVVaufV8PNf4qSslFTD8VMOxNVhHCjTw==",
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.2",
|
||||
"yallist": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"yallist": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
||||
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
|
||||
}
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"minizlib": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz",
|
||||
"integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==",
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
|
||||
"integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
|
||||
"requires": {
|
||||
"minipass": "^2.9.0"
|
||||
"minipass": "^3.0.0",
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"mixin-deep": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
|
||||
"integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"for-in": "^1.0.2",
|
||||
"is-extendable": "^1.0.1"
|
||||
@@ -17810,6 +17705,7 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
|
||||
"integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-plain-object": "^2.0.4"
|
||||
}
|
||||
@@ -17885,6 +17781,7 @@
|
||||
"version": "1.2.13",
|
||||
"resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
|
||||
"integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"arr-diff": "^4.0.0",
|
||||
"array-unique": "^0.3.2",
|
||||
@@ -17906,9 +17803,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"needle": {
|
||||
"version": "2.8.0",
|
||||
"resolved": "https://registry.npmjs.org/needle/-/needle-2.8.0.tgz",
|
||||
"integrity": "sha512-ZTq6WYkN/3782H1393me3utVYdq2XyqNUFBsprEE3VMAT0+hP/cItpnITpqsY6ep2yeFE4Tqtqwc74VqUlUYtw==",
|
||||
"version": "2.9.1",
|
||||
"resolved": "https://registry.npmjs.org/needle/-/needle-2.9.1.tgz",
|
||||
"integrity": "sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==",
|
||||
"requires": {
|
||||
"debug": "^3.2.6",
|
||||
"iconv-lite": "^0.4.4",
|
||||
@@ -17941,15 +17838,6 @@
|
||||
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
|
||||
"dev": true
|
||||
},
|
||||
"new-relic-source-map-webpack-plugin": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/new-relic-source-map-webpack-plugin/-/new-relic-source-map-webpack-plugin-1.2.0.tgz",
|
||||
"integrity": "sha512-bsF07nt2mlauMhxdKW3aIirazreq5muRLHSxubQ18XVqYR2ta0N6CghwHNDJsivY1j/Qrt22FNFuz0GZrFPbTw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@newrelic/publish-sourcemap": "^4.4.1"
|
||||
}
|
||||
},
|
||||
"next-tick": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
|
||||
@@ -18048,9 +17936,9 @@
|
||||
}
|
||||
},
|
||||
"node-releases": {
|
||||
"version": "1.1.74",
|
||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.74.tgz",
|
||||
"integrity": "sha512-caJBVempXZPepZoZAPCWRTNxYQ+xtG/KAi4ozTA5A+nJ7IU+kLQCbqaUjb5Rwy14M9upBWiQ4NutcmW04LJSRw==",
|
||||
"version": "1.1.75",
|
||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.75.tgz",
|
||||
"integrity": "sha512-Qe5OUajvqrqDSy6wrWFmMwfJ0jVgwiw4T3KqmbTcZ62qW0gQkheXYhcFM1+lOVcGUoRxcEcfyvFMAnDgaF1VWw==",
|
||||
"dev": true
|
||||
},
|
||||
"normalize-package-data": {
|
||||
@@ -18152,6 +18040,7 @@
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
|
||||
"integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"copy-descriptor": "^0.1.0",
|
||||
"define-property": "^0.2.5",
|
||||
@@ -18162,6 +18051,7 @@
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
|
||||
"integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-descriptor": "^0.1.0"
|
||||
}
|
||||
@@ -18170,6 +18060,7 @@
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
|
||||
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-buffer": "^1.1.5"
|
||||
}
|
||||
@@ -18204,6 +18095,7 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
|
||||
"integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"isobject": "^3.0.0"
|
||||
}
|
||||
@@ -18257,6 +18149,7 @@
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
|
||||
"integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"isobject": "^3.0.1"
|
||||
}
|
||||
@@ -18609,7 +18502,8 @@
|
||||
"pascalcase": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
|
||||
"integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ="
|
||||
"integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
|
||||
"dev": true
|
||||
},
|
||||
"path-dirname": {
|
||||
"version": "1.0.2",
|
||||
@@ -18695,12 +18589,13 @@
|
||||
}
|
||||
},
|
||||
"pino": {
|
||||
"version": "6.13.0",
|
||||
"resolved": "https://registry.npmjs.org/pino/-/pino-6.13.0.tgz",
|
||||
"integrity": "sha512-mRXSTfa34tbfrWqCIp1sUpZLqBhcoaGapoyxfEwaWwJGMpLijlRdDKIQUyvq4M3DUfFH5vEglwSw8POZYwbThA==",
|
||||
"version": "6.13.3",
|
||||
"resolved": "https://registry.npmjs.org/pino/-/pino-6.13.3.tgz",
|
||||
"integrity": "sha512-tJy6qVgkh9MwNgqX1/oYi3ehfl2Y9H0uHyEEMsBe74KinESIjdMrMQDWpcZPpPicg3VV35d/GLQZmo4QgU2Xkg==",
|
||||
"requires": {
|
||||
"fast-redact": "^3.0.0",
|
||||
"fast-safe-stringify": "^2.0.8",
|
||||
"fastify-warning": "^0.2.0",
|
||||
"flatstr": "^1.0.12",
|
||||
"pino-std-serializers": "^3.1.0",
|
||||
"quick-format-unescaped": "^4.0.3",
|
||||
@@ -18766,19 +18661,6 @@
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"requires": {
|
||||
"has-flag": "^4.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -19057,7 +18939,8 @@
|
||||
"posix-character-classes": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
|
||||
"integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs="
|
||||
"integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
|
||||
"dev": true
|
||||
},
|
||||
"postcss": {
|
||||
"version": "8.3.5",
|
||||
@@ -19181,13 +19064,13 @@
|
||||
}
|
||||
},
|
||||
"postcss-minify-gradients": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.0.1.tgz",
|
||||
"integrity": "sha512-odOwBFAIn2wIv+XYRpoN2hUV3pPQlgbJ10XeXPq8UY2N+9ZG42xu45lTn/g9zZ+d70NKSQD6EOi6UiCMu3FN7g==",
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.0.2.tgz",
|
||||
"integrity": "sha512-7Do9JP+wqSD6Prittitt2zDLrfzP9pqKs2EcLX7HJYxsxCOwrrcLt4x/ctQTsiOw+/8HYotAoqNkrzItL19SdQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"colord": "^2.6",
|
||||
"cssnano-utils": "^2.0.1",
|
||||
"is-color-stop": "^1.1.0",
|
||||
"postcss-value-parser": "^4.1.0"
|
||||
}
|
||||
},
|
||||
@@ -19392,40 +19275,6 @@
|
||||
"svgo": "^2.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"chalk": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-name": "~1.1.4"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true
|
||||
},
|
||||
"commander": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
|
||||
@@ -19505,13 +19354,13 @@
|
||||
}
|
||||
},
|
||||
"svgo": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/svgo/-/svgo-2.3.1.tgz",
|
||||
"integrity": "sha512-riDDIQgXpEnn0BEl9Gvhh1LNLIyiusSpt64IR8upJu7MwxnzetmF/Y57pXQD2NMX2lVyMRzXt5f2M5rO4wG7Dw==",
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/svgo/-/svgo-2.4.0.tgz",
|
||||
"integrity": "sha512-W25S1UUm9Lm9VnE0TvCzL7aso/NCzDEaXLaElCUO/KaVitw0+IBicSVfM1L1c0YHK5TOFh73yQ2naCpVHEQ/OQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@trysound/sax": "0.1.1",
|
||||
"chalk": "^4.1.0",
|
||||
"colorette": "^1.2.2",
|
||||
"commander": "^7.1.0",
|
||||
"css-select": "^4.1.3",
|
||||
"css-tree": "^1.1.2",
|
||||
@@ -19608,14 +19457,6 @@
|
||||
"requires": {
|
||||
"colors": "^1.1.2",
|
||||
"minimist": "^1.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"colors": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
|
||||
"integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"process-nextick-args": {
|
||||
@@ -19733,8 +19574,6 @@
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
|
||||
"integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"decode-uri-component": "^0.2.0",
|
||||
"object-assign": "^4.1.0",
|
||||
@@ -19754,9 +19593,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"quick-format-unescaped": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.3.tgz",
|
||||
"integrity": "sha512-MaL/oqh02mhEo5m5J2rwsVL23Iw2PEaGVHgT2vFt8AAsr0lfvQA5dpXo9TPu0rz7tSBdUPgkbam0j/fj5ZM8yg=="
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz",
|
||||
"integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg=="
|
||||
},
|
||||
"randombytes": {
|
||||
"version": "2.1.0",
|
||||
@@ -19793,9 +19632,9 @@
|
||||
}
|
||||
},
|
||||
"react-bootstrap": {
|
||||
"version": "1.6.1",
|
||||
"resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-1.6.1.tgz",
|
||||
"integrity": "sha512-ojEPQ6OtyIMdLg0Smofk+85PKN6MLKQX3bU0Vwmok/4yNa8DQ2vCGhO2IgHJvT+ERQZ4X+gAQcdn6msAHSwLBg==",
|
||||
"version": "1.6.3",
|
||||
"resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-1.6.3.tgz",
|
||||
"integrity": "sha512-zsd4l0g68pusOmJ/R5LhTfofT+9RniCwcZsMMNFGJo97d1vT1H2nGlbhLWp/j/pfeXXj9zzR8ugUtKkadcoWnA==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.14.0",
|
||||
"@restart/context": "^2.1.4",
|
||||
@@ -19810,7 +19649,7 @@
|
||||
"invariant": "^2.2.4",
|
||||
"prop-types": "^15.7.2",
|
||||
"prop-types-extra": "^1.1.0",
|
||||
"react-overlays": "^5.0.1",
|
||||
"react-overlays": "^5.1.1",
|
||||
"react-transition-group": "^4.4.1",
|
||||
"uncontrollable": "^7.2.1",
|
||||
"warning": "^4.0.3"
|
||||
@@ -19973,15 +19812,6 @@
|
||||
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
|
||||
"dev": true
|
||||
},
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
@@ -20103,9 +19933,9 @@
|
||||
"integrity": "sha1-acLVdB5t9eCPIw82u8KUTuEiJVU="
|
||||
},
|
||||
"react-redux": {
|
||||
"version": "7.2.4",
|
||||
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.4.tgz",
|
||||
"integrity": "sha512-hOQ5eOSkEJEXdpIKbnRyl04LhaWabkDPV+Ix97wqQX3T3d2NQ8DUblNXXtNMavc7DpswyQM6xfaN4HQDKNY2JA==",
|
||||
"version": "7.2.5",
|
||||
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.5.tgz",
|
||||
"integrity": "sha512-Dt29bNyBsbQaysp6s/dN0gUodcq+dVKKER8Qv82UrpeygwYeX1raTtil7O/fftw/rFqzaf6gJhDZRkkZnn6bjg==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.12.1",
|
||||
"@types/react-redux": "^7.1.16",
|
||||
@@ -20154,11 +19984,11 @@
|
||||
}
|
||||
},
|
||||
"react-router": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz",
|
||||
"integrity": "sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==",
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.1.tgz",
|
||||
"integrity": "sha512-lIboRiOtDLFdg1VTemMwud9vRVuOCZmUIT/7lUoZiSpPODiiH1UQlfXy+vPLC/7IWdFYnhRwAyNqA/+I7wnvKQ==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.1.2",
|
||||
"@babel/runtime": "^7.12.13",
|
||||
"history": "^4.9.0",
|
||||
"hoist-non-react-statics": "^3.1.0",
|
||||
"loose-envify": "^1.3.1",
|
||||
@@ -20171,15 +20001,15 @@
|
||||
}
|
||||
},
|
||||
"react-router-dom": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.0.tgz",
|
||||
"integrity": "sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==",
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.1.tgz",
|
||||
"integrity": "sha512-xhFFkBGVcIVPbWM2KEYzED+nuHQPmulVa7sqIs3ESxzYd1pYg8N8rxPnQ4T2o1zu/2QeDUWcaqST131SO1LR3w==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.1.2",
|
||||
"@babel/runtime": "^7.12.13",
|
||||
"history": "^4.9.0",
|
||||
"loose-envify": "^1.3.1",
|
||||
"prop-types": "^15.6.2",
|
||||
"react-router": "5.2.0",
|
||||
"react-router": "5.2.1",
|
||||
"tiny-invariant": "^1.0.2",
|
||||
"tiny-warning": "^1.0.0"
|
||||
}
|
||||
@@ -20458,6 +20288,7 @@
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
|
||||
"integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"extend-shallow": "^3.0.2",
|
||||
"safe-regex": "^1.1.0"
|
||||
@@ -20622,12 +20453,14 @@
|
||||
"repeat-element": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz",
|
||||
"integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ=="
|
||||
"integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==",
|
||||
"dev": true
|
||||
},
|
||||
"repeat-string": {
|
||||
"version": "1.6.1",
|
||||
"resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
|
||||
"integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc="
|
||||
"integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
|
||||
"dev": true
|
||||
},
|
||||
"repeating": {
|
||||
"version": "2.0.1",
|
||||
@@ -20708,7 +20541,8 @@
|
||||
"resolve-url": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
|
||||
"integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo="
|
||||
"integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
|
||||
"dev": true
|
||||
},
|
||||
"resolve-url-loader": {
|
||||
"version": "5.0.0-beta.1",
|
||||
@@ -20746,7 +20580,8 @@
|
||||
"ret": {
|
||||
"version": "0.1.15",
|
||||
"resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
|
||||
"integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg=="
|
||||
"integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
|
||||
"dev": true
|
||||
},
|
||||
"retry": {
|
||||
"version": "0.13.1",
|
||||
@@ -20765,18 +20600,6 @@
|
||||
"resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz",
|
||||
"integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA=="
|
||||
},
|
||||
"rgb-regex": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz",
|
||||
"integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=",
|
||||
"dev": true
|
||||
},
|
||||
"rgba-regex": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz",
|
||||
"integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=",
|
||||
"dev": true
|
||||
},
|
||||
"rimraf": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
|
||||
@@ -20928,6 +20751,7 @@
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
|
||||
"integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ret": "~0.1.10"
|
||||
}
|
||||
@@ -21176,6 +21000,7 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
|
||||
"integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"extend-shallow": "^2.0.1",
|
||||
"is-extendable": "^0.1.1",
|
||||
@@ -21187,6 +21012,7 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
|
||||
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-extendable": "^0.1.0"
|
||||
}
|
||||
@@ -21296,6 +21122,7 @@
|
||||
"version": "0.8.2",
|
||||
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
|
||||
"integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"base": "^0.11.1",
|
||||
"debug": "^2.2.0",
|
||||
@@ -21311,6 +21138,7 @@
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
|
||||
"integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-descriptor": "^0.1.0"
|
||||
}
|
||||
@@ -21319,6 +21147,7 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
|
||||
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-extendable": "^0.1.0"
|
||||
}
|
||||
@@ -21326,7 +21155,8 @@
|
||||
"source-map": {
|
||||
"version": "0.5.7",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
|
||||
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
|
||||
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -21334,6 +21164,7 @@
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
|
||||
"integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"define-property": "^1.0.0",
|
||||
"isobject": "^3.0.0",
|
||||
@@ -21344,6 +21175,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
|
||||
"integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-descriptor": "^1.0.0"
|
||||
}
|
||||
@@ -21352,6 +21184,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
|
||||
"integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^6.0.0"
|
||||
}
|
||||
@@ -21360,6 +21193,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
|
||||
"integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^6.0.0"
|
||||
}
|
||||
@@ -21368,6 +21202,7 @@
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
|
||||
"integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-accessor-descriptor": "^1.0.0",
|
||||
"is-data-descriptor": "^1.0.0",
|
||||
@@ -21380,6 +21215,7 @@
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
|
||||
"integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^3.2.0"
|
||||
},
|
||||
@@ -21388,6 +21224,7 @@
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
|
||||
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-buffer": "^1.1.5"
|
||||
}
|
||||
@@ -21406,9 +21243,9 @@
|
||||
}
|
||||
},
|
||||
"sonic-boom": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-2.1.0.tgz",
|
||||
"integrity": "sha512-x2j9LXx27EDlyZEC32gBM+scNVMdPutU7FIKV2BOTKCnPrp7bY5BsplCMQ4shYYR3IhDSIrEXoqb6GlS+z7KyQ==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-2.3.0.tgz",
|
||||
"integrity": "sha512-lEPaw654/4/rCJHz/TNzV4GIthqCq4inO+O3aFhbdOvR1bE+2//sVkcS+xlqPdb8gdjQCEE0hE9BuvnVixbnWQ==",
|
||||
"requires": {
|
||||
"atomic-sleep": "^1.0.0"
|
||||
}
|
||||
@@ -21487,6 +21324,7 @@
|
||||
"version": "0.5.3",
|
||||
"resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
|
||||
"integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"atob": "^2.1.2",
|
||||
"decode-uri-component": "^0.2.0",
|
||||
@@ -21508,7 +21346,8 @@
|
||||
"source-map-url": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz",
|
||||
"integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw=="
|
||||
"integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==",
|
||||
"dev": true
|
||||
},
|
||||
"spawn-sync": {
|
||||
"version": "1.0.15",
|
||||
@@ -21617,6 +21456,7 @@
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
|
||||
"integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"extend-shallow": "^3.0.0"
|
||||
}
|
||||
@@ -21733,6 +21573,7 @@
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
|
||||
"integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"define-property": "^0.2.5",
|
||||
"object-copy": "^0.1.0"
|
||||
@@ -21742,6 +21583,7 @@
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
|
||||
"integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-descriptor": "^0.1.0"
|
||||
}
|
||||
@@ -21765,9 +21607,7 @@
|
||||
"strict-uri-encode": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
|
||||
"integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM="
|
||||
},
|
||||
"string-length": {
|
||||
"version": "4.0.2",
|
||||
@@ -21888,20 +21728,12 @@
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
|
||||
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
|
||||
"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": "^4.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
|
||||
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
|
||||
"dev": true
|
||||
}
|
||||
"ansi-regex": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"strip-bom": {
|
||||
@@ -22066,7 +21898,6 @@
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-flag": "^4.0.0"
|
||||
},
|
||||
@@ -22074,8 +21905,7 @@
|
||||
"has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -22176,6 +22006,12 @@
|
||||
"string-width": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
|
||||
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
|
||||
"dev": true
|
||||
},
|
||||
"emoji-regex": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
|
||||
@@ -22198,6 +22034,15 @@
|
||||
"is-fullwidth-code-point": "^2.0.0",
|
||||
"strip-ansi": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
|
||||
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^4.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -22381,23 +22226,22 @@
|
||||
"dev": true
|
||||
},
|
||||
"tar": {
|
||||
"version": "4.4.2",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-4.4.2.tgz",
|
||||
"integrity": "sha512-BfkE9CciGGgDsATqkikUHrQrraBCO+ke/1f6SFAEMnxyyfN9lxC+nW1NFWMpqH865DhHIy9vQi682gk1X7friw==",
|
||||
"version": "6.1.11",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
|
||||
"integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==",
|
||||
"requires": {
|
||||
"chownr": "^1.0.1",
|
||||
"fs-minipass": "^1.2.5",
|
||||
"minipass": "^2.2.4",
|
||||
"minizlib": "^1.1.0",
|
||||
"mkdirp": "^0.5.0",
|
||||
"safe-buffer": "^5.1.2",
|
||||
"yallist": "^3.0.2"
|
||||
"chownr": "^2.0.0",
|
||||
"fs-minipass": "^2.0.0",
|
||||
"minipass": "^3.0.0",
|
||||
"minizlib": "^2.1.1",
|
||||
"mkdirp": "^1.0.3",
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"yallist": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
||||
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
|
||||
"mkdirp": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
|
||||
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -22702,6 +22546,7 @@
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
|
||||
"integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^3.0.2"
|
||||
},
|
||||
@@ -22710,6 +22555,7 @@
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
|
||||
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-buffer": "^1.1.5"
|
||||
}
|
||||
@@ -22720,6 +22566,7 @@
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
|
||||
"integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"define-property": "^2.0.2",
|
||||
"extend-shallow": "^3.0.2",
|
||||
@@ -22731,6 +22578,7 @@
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
|
||||
"integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-number": "^3.0.0",
|
||||
"repeat-string": "^1.6.1"
|
||||
@@ -22957,6 +22805,7 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
|
||||
"integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"arr-union": "^3.1.0",
|
||||
"get-value": "^2.0.6",
|
||||
@@ -23018,6 +22867,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
|
||||
"integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-value": "^0.3.1",
|
||||
"isobject": "^3.0.0"
|
||||
@@ -23027,6 +22877,7 @@
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
|
||||
"integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"get-value": "^2.0.3",
|
||||
"has-values": "^0.1.4",
|
||||
@@ -23037,6 +22888,7 @@
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
|
||||
"integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"isarray": "1.0.0"
|
||||
}
|
||||
@@ -23046,12 +22898,14 @@
|
||||
"has-values": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
|
||||
"integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E="
|
||||
"integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
|
||||
"dev": true
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -23129,7 +22983,8 @@
|
||||
"urix": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
|
||||
"integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI="
|
||||
"integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
|
||||
"dev": true
|
||||
},
|
||||
"url": {
|
||||
"version": "0.11.0",
|
||||
@@ -23194,7 +23049,8 @@
|
||||
"use": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
|
||||
"integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ=="
|
||||
"integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
|
||||
"dev": true
|
||||
},
|
||||
"use-callback-ref": {
|
||||
"version": "1.2.5",
|
||||
@@ -23369,9 +23225,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"webpack": {
|
||||
"version": "5.44.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.44.0.tgz",
|
||||
"integrity": "sha512-I1S1w4QLoKmH19pX6YhYN0NiSXaWY8Ou00oA+aMcr9IUGeF5azns+IKBkfoAAG9Bu5zOIzZt/mN35OffBya8AQ==",
|
||||
"version": "5.50.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.50.0.tgz",
|
||||
"integrity": "sha512-hqxI7t/KVygs0WRv/kTgUW8Kl3YC81uyWQSo/7WUs5LsuRw0htH/fCwbVBGCuiX/t4s7qzjXFcf41O8Reiypag==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/eslint-scope": "^3.7.0",
|
||||
@@ -23380,6 +23236,7 @@
|
||||
"@webassemblyjs/wasm-edit": "1.11.1",
|
||||
"@webassemblyjs/wasm-parser": "1.11.1",
|
||||
"acorn": "^8.4.1",
|
||||
"acorn-import-assertions": "^1.7.6",
|
||||
"browserslist": "^4.14.5",
|
||||
"chrome-trace-event": "^1.0.2",
|
||||
"enhanced-resolve": "^5.8.0",
|
||||
@@ -23392,11 +23249,11 @@
|
||||
"loader-runner": "^4.2.0",
|
||||
"mime-types": "^2.1.27",
|
||||
"neo-async": "^2.6.2",
|
||||
"schema-utils": "^3.0.0",
|
||||
"schema-utils": "^3.1.0",
|
||||
"tapable": "^2.1.1",
|
||||
"terser-webpack-plugin": "^5.1.3",
|
||||
"watchpack": "^2.2.0",
|
||||
"webpack-sources": "^2.3.0"
|
||||
"webpack-sources": "^3.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"acorn": {
|
||||
@@ -23406,14 +23263,10 @@
|
||||
"dev": true
|
||||
},
|
||||
"webpack-sources": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.1.tgz",
|
||||
"integrity": "sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"source-list-map": "^2.0.1",
|
||||
"source-map": "^0.6.1"
|
||||
}
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.0.tgz",
|
||||
"integrity": "sha512-fahN08Et7P9trej8xz/Z7eRu8ltyiygEo/hnRi9KqBUs80KeDcnf96ZJo++ewWd84fEf3xSX9bp4ZS9hbw0OBw==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -23462,15 +23315,15 @@
|
||||
}
|
||||
},
|
||||
"webpack-cli": {
|
||||
"version": "4.7.2",
|
||||
"resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.7.2.tgz",
|
||||
"integrity": "sha512-mEoLmnmOIZQNiRl0ebnjzQ74Hk0iKS5SiEEnpq3dRezoyR3yPaeQZCMCe+db4524pj1Pd5ghZXjT41KLzIhSLw==",
|
||||
"version": "4.8.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.8.0.tgz",
|
||||
"integrity": "sha512-+iBSWsX16uVna5aAYN6/wjhJy1q/GKk4KjKvfg90/6hykCTSgozbfz5iRgDTSJt/LgSbYxdBX3KBHeobIs+ZEw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@discoveryjs/json-ext": "^0.5.0",
|
||||
"@webpack-cli/configtest": "^1.0.4",
|
||||
"@webpack-cli/info": "^1.3.0",
|
||||
"@webpack-cli/serve": "^1.5.1",
|
||||
"@webpack-cli/serve": "^1.5.2",
|
||||
"colorette": "^1.2.1",
|
||||
"commander": "^7.0.0",
|
||||
"execa": "^5.0.0",
|
||||
@@ -23580,54 +23433,75 @@
|
||||
}
|
||||
},
|
||||
"webpack-dev-middleware": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-4.3.0.tgz",
|
||||
"integrity": "sha512-PjwyVY95/bhBh6VUqt6z4THplYcsvQ8YNNBTBM873xLVmw8FLeALn0qurHbs9EmcfhzQis/eoqypSnZeuUz26w==",
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.0.0.tgz",
|
||||
"integrity": "sha512-9zng2Z60pm6A98YoRcA0wSxw1EYn7B7y5owX/Tckyt9KGyULTkLtiavjaXlWqOMkM0YtqGgL3PvMOFgyFLq8vw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"colorette": "^1.2.2",
|
||||
"mem": "^8.1.1",
|
||||
"memfs": "^3.2.2",
|
||||
"mime-types": "^2.1.30",
|
||||
"mime-types": "^2.1.31",
|
||||
"range-parser": "^1.2.1",
|
||||
"schema-utils": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"mime-db": {
|
||||
"version": "1.49.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz",
|
||||
"integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==",
|
||||
"dev": true
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.32",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz",
|
||||
"integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"mime-db": "1.49.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"webpack-dev-server": {
|
||||
"version": "4.0.0-beta.3",
|
||||
"resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.0.0-beta.3.tgz",
|
||||
"integrity": "sha512-Ud7ieH15No/KiSdRuzk+2k+S4gSCR/N7m4hJhesDbKQEZy3P+NPXTXfsimNOZvbVX2TRuIEFB+VdLZFn8DwGwg==",
|
||||
"version": "4.0.0-rc.1",
|
||||
"resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.0.0-rc.1.tgz",
|
||||
"integrity": "sha512-gZlGe0CMA0YZ5bIXFbtSegd33tYsUujYv+rgJu9Y75xHvXBSXFJiBvakMV7yTkBE+k8dgz4VsBzl7J5I5xatyg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-html": "^0.0.7",
|
||||
"bonjour": "^3.5.0",
|
||||
"chokidar": "^3.5.1",
|
||||
"colorette": "^1.2.2",
|
||||
"compression": "^1.7.4",
|
||||
"connect-history-api-fallback": "^1.6.0",
|
||||
"del": "^6.0.0",
|
||||
"express": "^4.17.1",
|
||||
"find-cache-dir": "^3.3.1",
|
||||
"graceful-fs": "^4.2.6",
|
||||
"html-entities": "^2.3.2",
|
||||
"http-proxy-middleware": "^1.3.1",
|
||||
"http-proxy-middleware": "^2.0.0",
|
||||
"internal-ip": "^6.2.0",
|
||||
"ipaddr.js": "^2.0.0",
|
||||
"is-absolute-url": "^3.0.3",
|
||||
"killable": "^1.0.1",
|
||||
"open": "^7.4.2",
|
||||
"ipaddr.js": "^2.0.1",
|
||||
"open": "^8.0.9",
|
||||
"p-retry": "^4.5.0",
|
||||
"portfinder": "^1.0.28",
|
||||
"schema-utils": "^3.0.0",
|
||||
"schema-utils": "^3.1.0",
|
||||
"selfsigned": "^1.10.11",
|
||||
"serve-index": "^1.9.1",
|
||||
"sockjs": "^0.3.21",
|
||||
"spdy": "^4.0.2",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"strip-ansi": "^7.0.0",
|
||||
"url": "^0.11.0",
|
||||
"webpack-dev-middleware": "^4.1.0",
|
||||
"ws": "^7.4.5"
|
||||
"webpack-dev-middleware": "^5.0.0",
|
||||
"ws": "^8.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.0.tgz",
|
||||
"integrity": "sha512-tAaOSrWCHF+1Ear1Z4wnJCXA9GGox4K6Ic85a5qalES2aeEwQGr7UC93mwef49536PkCYjzkp0zIxfFvexJ6zQ==",
|
||||
"dev": true
|
||||
},
|
||||
"anymatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
|
||||
@@ -23700,17 +23574,6 @@
|
||||
"to-regex-range": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"find-cache-dir": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz",
|
||||
"integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"commondir": "^1.0.1",
|
||||
"make-dir": "^3.0.2",
|
||||
"pkg-dir": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"fsevents": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||
@@ -23742,9 +23605,9 @@
|
||||
}
|
||||
},
|
||||
"http-proxy-middleware": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-1.3.1.tgz",
|
||||
"integrity": "sha512-13eVVDYS4z79w7f1+NPllJtOQFx/FdUW4btIvVRMaRlUY9VGstAbo5MOhLEuUgZFRHn3x50ufn25zkj/boZnEg==",
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.1.tgz",
|
||||
"integrity": "sha512-cfaXRVoZxSed/BmkA7SwBVNI9Kj7HFltaE5rqYOub5kWzWZ+gofV2koVN1j2rMW7pEfSSlCHGJ31xmuyFyfLOg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/http-proxy": "^1.17.5",
|
||||
@@ -23793,15 +23656,6 @@
|
||||
"integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==",
|
||||
"dev": true
|
||||
},
|
||||
"make-dir": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
|
||||
"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"semver": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"micromatch": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
|
||||
@@ -23812,6 +23666,17 @@
|
||||
"picomatch": "^2.2.3"
|
||||
}
|
||||
},
|
||||
"open": {
|
||||
"version": "8.2.1",
|
||||
"resolved": "https://registry.npmjs.org/open/-/open-8.2.1.tgz",
|
||||
"integrity": "sha512-rXILpcQlkF/QuFez2BJDf3GsqpjGKbkUUToAIGo9A0Q6ZkoSGogZJulrUdwRkrAsoQvoZsrjCYt8+zblOk7JQQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"define-lazy-prop": "^2.0.0",
|
||||
"is-docker": "^2.1.1",
|
||||
"is-wsl": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"p-map": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
|
||||
@@ -23821,15 +23686,6 @@
|
||||
"aggregate-error": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"pkg-dir": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
|
||||
"integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"find-up": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"readdirp": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
||||
@@ -23848,12 +23704,6 @@
|
||||
"glob": "^7.1.3"
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
||||
"dev": true
|
||||
},
|
||||
"slash": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
|
||||
@@ -23861,12 +23711,12 @@
|
||||
"dev": true
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
|
||||
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-UhDTSnGF1dc0DRbUqr1aXwNoY3RgVkSWG8BrpnuFIxhP57IqbS7IRta2Gfiavds4yCxc5+fEAVVOgBZWnYkvzg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^5.0.0"
|
||||
"ansi-regex": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"to-regex-range": {
|
||||
@@ -23877,6 +23727,12 @@
|
||||
"requires": {
|
||||
"is-number": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"ws": {
|
||||
"version": "8.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.2.0.tgz",
|
||||
"integrity": "sha512-uYhVJ/m9oXwEI04iIVmgLmugh2qrZihkywG9y5FfZV2ATeLIzHf93qs+tUNqlttbQK957/VX3mtwAS+UfIwA4g==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -24064,9 +23920,9 @@
|
||||
}
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
|
||||
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
@@ -24097,15 +23953,6 @@
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true
|
||||
},
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -24170,16 +24017,15 @@
|
||||
"optional": true
|
||||
},
|
||||
"y18n": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
|
||||
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
|
||||
"dev": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||
"dev": true
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
},
|
||||
"yaml": {
|
||||
"version": "1.10.2",
|
||||
@@ -24188,41 +24034,25 @@
|
||||
"dev": true
|
||||
},
|
||||
"yargs": {
|
||||
"version": "15.4.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
|
||||
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
|
||||
"version": "16.2.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
|
||||
"integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cliui": "^6.0.0",
|
||||
"decamelize": "^1.2.0",
|
||||
"find-up": "^4.1.0",
|
||||
"get-caller-file": "^2.0.1",
|
||||
"cliui": "^7.0.2",
|
||||
"escalade": "^3.1.1",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"require-directory": "^2.1.1",
|
||||
"require-main-filename": "^2.0.0",
|
||||
"set-blocking": "^2.0.0",
|
||||
"string-width": "^4.2.0",
|
||||
"which-module": "^2.0.0",
|
||||
"y18n": "^4.0.0",
|
||||
"yargs-parser": "^18.1.2"
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^20.2.2"
|
||||
}
|
||||
},
|
||||
"yargs-parser": {
|
||||
"version": "18.1.3",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
|
||||
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"camelcase": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
|
||||
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
"version": "20.2.9",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
|
||||
"integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
|
||||
"dev": true
|
||||
},
|
||||
"yauzl": {
|
||||
"version": "2.10.0",
|
||||
|
||||
30
package.json
30
package.json
@@ -33,19 +33,19 @@
|
||||
"dependencies": {
|
||||
"@edx/brand": "npm:@edx/brand-openedx@1.1.0",
|
||||
"@edx/frontend-component-footer": "10.1.6",
|
||||
"@edx/frontend-enterprise-utils": "0.1.7",
|
||||
"@edx/frontend-lib-special-exams": "1.12.0",
|
||||
"@edx/frontend-platform": "1.12.3",
|
||||
"@edx/paragon": "16.7.0",
|
||||
"@edx/frontend-enterprise-utils": "1.0.0",
|
||||
"@edx/frontend-lib-special-exams": "1.13.3",
|
||||
"@edx/frontend-platform": "1.12.7",
|
||||
"@edx/paragon": "16.13.3",
|
||||
"@fortawesome/fontawesome-svg-core": "1.2.36",
|
||||
"@fortawesome/free-brands-svg-icons": "5.15.4",
|
||||
"@fortawesome/free-regular-svg-icons": "5.15.4",
|
||||
"@fortawesome/free-solid-svg-icons": "5.15.4",
|
||||
"@fortawesome/react-fontawesome": "0.1.15",
|
||||
"@pact-foundation/pact": "9.16.0",
|
||||
"@reduxjs/toolkit": "1.6.1",
|
||||
"@pact-foundation/pact": "9.16.3",
|
||||
"@reduxjs/toolkit": "1.6.2",
|
||||
"classnames": "2.3.1",
|
||||
"core-js": "3.16.1",
|
||||
"core-js": "3.16.4",
|
||||
"js-cookie": "2.2.1",
|
||||
"lodash.camelcase": "4.3.0",
|
||||
"prop-types": "15.7.2",
|
||||
@@ -53,9 +53,9 @@
|
||||
"react-break": "1.3.2",
|
||||
"react-dom": "17.0.2",
|
||||
"react-helmet": "6.1.0",
|
||||
"react-redux": "7.2.4",
|
||||
"react-router": "5.2.0",
|
||||
"react-router-dom": "5.2.0",
|
||||
"react-redux": "7.2.5",
|
||||
"react-router": "5.2.1",
|
||||
"react-router-dom": "5.2.1",
|
||||
"react-share": "4.4.0",
|
||||
"redux": "4.1.1",
|
||||
"regenerator-runtime": "0.13.9",
|
||||
@@ -64,16 +64,16 @@
|
||||
"util": "0.12.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@edx/frontend-build": "8.0.0",
|
||||
"@edx/frontend-build": "8.0.4",
|
||||
"@testing-library/dom": "7.16.3",
|
||||
"@testing-library/jest-dom": "5.14.1",
|
||||
"@testing-library/react": "10.3.0",
|
||||
"@testing-library/user-event": "12.8.3",
|
||||
"axios-mock-adapter": "1.19.0",
|
||||
"@testing-library/user-event": "13.2.1",
|
||||
"axios-mock-adapter": "1.20.0",
|
||||
"codecov": "3.8.3",
|
||||
"es-check": "5.2.4",
|
||||
"es-check": "6.0.0",
|
||||
"glob": "7.1.7",
|
||||
"husky": "7.0.1",
|
||||
"husky": "7.0.2",
|
||||
"jest": "27.0.6",
|
||||
"jest-chain": "1.1.5",
|
||||
"reactifex": "1.1.1",
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -9,7 +9,6 @@ import { Info } from '@edx/paragon/icons';
|
||||
|
||||
import messages from './messages';
|
||||
import AccessExpirationAlertMMP2P from './AccessExpirationAlertMMP2P';
|
||||
import AccessExpirationAlertMasquerade from './AccessExpirationAlertMasquerade';
|
||||
|
||||
function AccessExpirationAlert({ intl, payload }) {
|
||||
/** [MM-P2P] Experiment */
|
||||
@@ -36,17 +35,10 @@ function AccessExpirationAlert({ intl, payload }) {
|
||||
|
||||
const {
|
||||
expirationDate,
|
||||
masqueradingExpiredCourse,
|
||||
upgradeDeadline,
|
||||
upgradeUrl,
|
||||
} = accessExpiration;
|
||||
|
||||
if (masqueradingExpiredCourse) {
|
||||
return (
|
||||
<AccessExpirationAlertMasquerade payload={payload} />
|
||||
);
|
||||
}
|
||||
|
||||
/** [MM-P2P] Experiment */
|
||||
if (showMMP2P) {
|
||||
return (
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage, FormattedDate } from '@edx/frontend-platform/i18n';
|
||||
import { Alert } from '@edx/paragon';
|
||||
import { Info } from '@edx/paragon/icons';
|
||||
|
||||
function AccessExpirationAlertMasquerade({ payload }) {
|
||||
const {
|
||||
accessExpiration,
|
||||
userTimezone,
|
||||
} = payload;
|
||||
|
||||
if (!accessExpiration) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const {
|
||||
expirationDate,
|
||||
masqueradingExpiredCourse,
|
||||
} = accessExpiration;
|
||||
|
||||
if (!masqueradingExpiredCourse) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const timezoneFormatArgs = userTimezone ? { timeZone: userTimezone } : {};
|
||||
|
||||
return (
|
||||
<Alert variant="info" icon={Info}>
|
||||
<FormattedMessage
|
||||
id="learning.accessExpiration.expired"
|
||||
defaultMessage="This learner does not have access to this course. Their access expired on {date}."
|
||||
values={{
|
||||
date: (
|
||||
<FormattedDate
|
||||
key="accessExpirationExpiredDate"
|
||||
day="numeric"
|
||||
month="short"
|
||||
year="numeric"
|
||||
value={expirationDate}
|
||||
{...timezoneFormatArgs}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</Alert>
|
||||
);
|
||||
}
|
||||
|
||||
AccessExpirationAlertMasquerade.propTypes = {
|
||||
payload: PropTypes.shape({
|
||||
accessExpiration: PropTypes.shape({
|
||||
expirationDate: PropTypes.string.isRequired,
|
||||
masqueradingExpiredCourse: PropTypes.bool.isRequired,
|
||||
}).isRequired,
|
||||
userTimezone: PropTypes.string.isRequired,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
export default AccessExpirationAlertMasquerade;
|
||||
@@ -0,0 +1,38 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage, FormattedDate } from '@edx/frontend-platform/i18n';
|
||||
import { PageBanner } from '@edx/paragon';
|
||||
|
||||
function AccessExpirationMasqueradeBanner({ payload }) {
|
||||
const {
|
||||
expirationDate,
|
||||
userTimezone,
|
||||
} = payload;
|
||||
|
||||
const timezoneFormatArgs = userTimezone ? { timeZone: userTimezone } : {};
|
||||
|
||||
return (
|
||||
<PageBanner variant="warning">
|
||||
<FormattedMessage
|
||||
id="instructorToolbar.pageBanner.courseHasExpired"
|
||||
defaultMessage="This learner no longer has access to this course. Their access expired on {date}."
|
||||
values={{
|
||||
date: <FormattedDate
|
||||
key="instructorToolbar.pageBanner.accessExpirationDate"
|
||||
value={expirationDate}
|
||||
{...timezoneFormatArgs}
|
||||
/>,
|
||||
}}
|
||||
/>
|
||||
</PageBanner>
|
||||
);
|
||||
}
|
||||
|
||||
AccessExpirationMasqueradeBanner.propTypes = {
|
||||
payload: PropTypes.shape({
|
||||
expirationDate: PropTypes.string.isRequired,
|
||||
userTimezone: PropTypes.string.isRequired,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
export default AccessExpirationMasqueradeBanner;
|
||||
@@ -1,11 +1,12 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import { useAlert } from '../../generic/user-messages';
|
||||
import { useModel } from '../../generic/model-store';
|
||||
|
||||
const AccessExpirationAlert = React.lazy(() => import('./AccessExpirationAlert'));
|
||||
const AccessExpirationAlertMasquerade = React.lazy(() => import('./AccessExpirationAlertMasquerade'));
|
||||
const AccessExpirationMasqueradeBanner = React.lazy(() => import('./AccessExpirationMasqueradeBanner'));
|
||||
|
||||
function useAccessExpirationAlert(accessExpiration, courseId, org, userTimezone, topic, analyticsPageName) {
|
||||
const isVisible = !!accessExpiration; // If it exists, show it.
|
||||
const isVisible = accessExpiration && !accessExpiration.masqueradingExpiredCourse; // If it exists, show it.
|
||||
const payload = {
|
||||
accessExpiration,
|
||||
courseId,
|
||||
@@ -23,20 +24,28 @@ function useAccessExpirationAlert(accessExpiration, courseId, org, userTimezone,
|
||||
return { clientAccessExpirationAlert: AccessExpirationAlert };
|
||||
}
|
||||
|
||||
export function useAccessExpirationAlertMasquerade(accessExpiration, userTimezone, topic) {
|
||||
const isVisible = !!accessExpiration; // If it exists, show it.
|
||||
const payload = {
|
||||
export function useAccessExpirationMasqueradeBanner(courseId, tab) {
|
||||
const {
|
||||
userTimezone,
|
||||
} = useModel('courseHomeMeta', courseId);
|
||||
const {
|
||||
accessExpiration,
|
||||
} = useModel(tab, courseId);
|
||||
|
||||
const isVisible = accessExpiration && accessExpiration.masqueradingExpiredCourse;
|
||||
const expirationDate = accessExpiration && accessExpiration.expirationDate;
|
||||
const payload = {
|
||||
expirationDate,
|
||||
userTimezone,
|
||||
};
|
||||
|
||||
useAlert(isVisible, {
|
||||
code: 'clientAccessExpirationAlertMasquerade',
|
||||
code: 'clientAccessExpirationMasqueradeBanner',
|
||||
payload: useMemo(() => payload, Object.values(payload).sort()),
|
||||
topic,
|
||||
topic: 'instructor-toolbar-alerts',
|
||||
});
|
||||
|
||||
return { clientAccessExpirationAlertMasquerade: AccessExpirationAlertMasquerade };
|
||||
return { clientAccessExpirationMasqueradeBanner: AccessExpirationMasqueradeBanner };
|
||||
}
|
||||
|
||||
export default useAccessExpirationAlert;
|
||||
|
||||
@@ -1 +1 @@
|
||||
export { default, useAccessExpirationAlertMasquerade } from './hooks';
|
||||
export { default, useAccessExpirationMasqueradeBanner } from './hooks';
|
||||
|
||||
@@ -9,14 +9,20 @@ import {
|
||||
import { Alert } from '@edx/paragon';
|
||||
import { Info } from '@edx/paragon/icons';
|
||||
|
||||
import { useModel } from '../../generic/model-store';
|
||||
|
||||
const DAY_MS = 24 * 60 * 60 * 1000; // in ms
|
||||
|
||||
function CourseStartAlert({ payload }) {
|
||||
const {
|
||||
startDate,
|
||||
userTimezone,
|
||||
courseId,
|
||||
} = payload;
|
||||
|
||||
const {
|
||||
start: startDate,
|
||||
userTimezone,
|
||||
} = useModel('courseHomeMeta', courseId);
|
||||
|
||||
const timezoneFormatArgs = userTimezone ? { timeZone: userTimezone } : {};
|
||||
|
||||
const timeRemaining = (
|
||||
@@ -87,8 +93,7 @@ function CourseStartAlert({ payload }) {
|
||||
|
||||
CourseStartAlert.propTypes = {
|
||||
payload: PropTypes.shape({
|
||||
startDate: PropTypes.string,
|
||||
userTimezone: PropTypes.string,
|
||||
courseId: PropTypes.string,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage, FormattedDate } from '@edx/frontend-platform/i18n';
|
||||
import { PageBanner } from '@edx/paragon';
|
||||
|
||||
import { useModel } from '../../generic/model-store';
|
||||
|
||||
function CourseStartMasqueradeBanner({ payload }) {
|
||||
const {
|
||||
courseId,
|
||||
} = payload;
|
||||
|
||||
const {
|
||||
start,
|
||||
userTimezone,
|
||||
} = useModel('courseHomeMeta', courseId);
|
||||
|
||||
const timezoneFormatArgs = userTimezone ? { timeZone: userTimezone } : {};
|
||||
|
||||
return (
|
||||
<PageBanner variant="warning">
|
||||
<FormattedMessage
|
||||
id="instructorToolbar.pageBanner.courseHasNotStarted"
|
||||
defaultMessage="This learner does not yet have access to this course. The course starts on {date}."
|
||||
values={{
|
||||
date: <FormattedDate
|
||||
key="instructorToolbar.pageBanner.courseStartDate"
|
||||
value={start}
|
||||
{...timezoneFormatArgs}
|
||||
/>,
|
||||
}}
|
||||
/>
|
||||
</PageBanner>
|
||||
);
|
||||
}
|
||||
|
||||
CourseStartMasqueradeBanner.propTypes = {
|
||||
payload: PropTypes.shape({
|
||||
courseId: PropTypes.string.isRequired,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
export default CourseStartMasqueradeBanner;
|
||||
62
src/alerts/course-start-alert/hooks.js
Normal file
62
src/alerts/course-start-alert/hooks.js
Normal file
@@ -0,0 +1,62 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import { useAlert } from '../../generic/user-messages';
|
||||
import { useModel } from '../../generic/model-store';
|
||||
|
||||
const CourseStartAlert = React.lazy(() => import('./CourseStartAlert'));
|
||||
const CourseStartMasqueradeBanner = React.lazy(() => import('./CourseStartMasqueradeBanner'));
|
||||
|
||||
function isStartDateInFuture(courseId) {
|
||||
const {
|
||||
start,
|
||||
} = useModel('courseHomeMeta', courseId);
|
||||
|
||||
const today = new Date();
|
||||
const startDate = new Date(start);
|
||||
return startDate > today;
|
||||
}
|
||||
|
||||
function useCourseStartAlert(courseId) {
|
||||
const {
|
||||
isEnrolled,
|
||||
} = useModel('courseHomeMeta', courseId);
|
||||
|
||||
const isVisible = isEnrolled && isStartDateInFuture(courseId);
|
||||
|
||||
const payload = {
|
||||
courseId,
|
||||
};
|
||||
|
||||
useAlert(isVisible, {
|
||||
code: 'clientCourseStartAlert',
|
||||
payload: useMemo(() => payload, Object.values(payload).sort()),
|
||||
topic: 'outline-course-alerts',
|
||||
});
|
||||
|
||||
return {
|
||||
clientCourseStartAlert: CourseStartAlert,
|
||||
};
|
||||
}
|
||||
|
||||
export function useCourseStartMasqueradeBanner(courseId, tab) {
|
||||
const {
|
||||
isMasquerading,
|
||||
} = useModel('courseHomeMeta', courseId);
|
||||
|
||||
const isVisible = isMasquerading && tab === 'progress' && isStartDateInFuture(courseId);
|
||||
|
||||
const payload = {
|
||||
courseId,
|
||||
};
|
||||
|
||||
useAlert(isVisible, {
|
||||
code: 'clientCourseStartMasqueradeBanner',
|
||||
payload: useMemo(() => payload, Object.values(payload).sort()),
|
||||
topic: 'instructor-toolbar-alerts',
|
||||
});
|
||||
|
||||
return {
|
||||
clientCourseStartMasqueradeBanner: CourseStartMasqueradeBanner,
|
||||
};
|
||||
}
|
||||
|
||||
export default useCourseStartAlert;
|
||||
1
src/alerts/course-start-alert/index.js
Normal file
1
src/alerts/course-start-alert/index.js
Normal file
@@ -0,0 +1 @@
|
||||
export { default, useCourseStartMasqueradeBanner } from './hooks';
|
||||
@@ -29,7 +29,7 @@ LinkedLogo.propTypes = {
|
||||
};
|
||||
|
||||
function Header({
|
||||
courseOrg, courseNumber, courseTitle, intl,
|
||||
courseOrg, courseNumber, courseTitle, intl, showUserDropdown,
|
||||
}) {
|
||||
const { authenticatedUser } = useContext(AppContext);
|
||||
|
||||
@@ -67,13 +67,13 @@ function Header({
|
||||
<span className="d-block small m-0">{courseOrg} {courseNumber}</span>
|
||||
<span className="d-block m-0 font-weight-bold course-title">{courseTitle}</span>
|
||||
</div>
|
||||
{authenticatedUser && (
|
||||
{showUserDropdown && authenticatedUser && (
|
||||
<AuthenticatedUserDropdown
|
||||
enterpriseLearnerPortalLink={enterpriseLearnerPortalLink}
|
||||
username={authenticatedUser.username}
|
||||
/>
|
||||
)}
|
||||
{!authenticatedUser && (
|
||||
{showUserDropdown && !authenticatedUser && (
|
||||
<AnonymousUserMenu />
|
||||
)}
|
||||
</div>
|
||||
@@ -86,12 +86,14 @@ Header.propTypes = {
|
||||
courseNumber: PropTypes.string,
|
||||
courseTitle: PropTypes.string,
|
||||
intl: intlShape.isRequired,
|
||||
showUserDropdown: PropTypes.bool,
|
||||
};
|
||||
|
||||
Header.defaultProps = {
|
||||
courseOrg: null,
|
||||
courseNumber: null,
|
||||
courseTitle: null,
|
||||
showUserDropdown: true,
|
||||
};
|
||||
|
||||
export default injectIntl(Header);
|
||||
|
||||
@@ -19,4 +19,5 @@ Factory.define('courseHomeMetadata')
|
||||
user_message: null,
|
||||
},
|
||||
start: '2013-02-05T05:00:00Z',
|
||||
user_timezone: 'UTC',
|
||||
});
|
||||
|
||||
@@ -219,5 +219,4 @@ Factory.define('datesTabData')
|
||||
],
|
||||
has_ended: false,
|
||||
learner_is_full_access: true,
|
||||
user_timezone: 'America/New_York',
|
||||
});
|
||||
|
||||
@@ -14,7 +14,6 @@ Factory.define('outlineTabData')
|
||||
})
|
||||
.attr('dates_widget', ['date_blocks'], (dateBlocks) => ({
|
||||
course_date_blocks: dateBlocks,
|
||||
user_timezone: 'UTC',
|
||||
}))
|
||||
.attr('resume_course', ['host', 'courseId'], (host, courseId) => ({
|
||||
has_visited_course: false,
|
||||
@@ -48,11 +47,6 @@ Factory.define('outlineTabData')
|
||||
title: 'Bookmarks',
|
||||
url: 'https://example.com/bookmarks',
|
||||
},
|
||||
{
|
||||
analytics_id: 'edx.tool.verified_upgrade',
|
||||
title: 'Upgrade to Verified',
|
||||
url: 'https://example.com/upgrade',
|
||||
},
|
||||
],
|
||||
dates_banner_info: {
|
||||
content_type_gating_enabled: false,
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Factory } from 'rosie'; // eslint-disable-line import/no-extraneous-dep
|
||||
// This set of data may not be realistic, but it is intended to demonstrate many UI results.
|
||||
Factory.define('progressTabData')
|
||||
.attrs({
|
||||
access_expiration: null,
|
||||
end: '3027-03-31T00:00:00Z',
|
||||
certificate_data: {},
|
||||
completion_summary: {
|
||||
|
||||
@@ -13,10 +13,8 @@ Object {
|
||||
"courseware": Object {
|
||||
"courseId": null,
|
||||
"courseStatus": "loading",
|
||||
"proctoredExamsEnabledWaffleFlag": false,
|
||||
"sequenceId": null,
|
||||
"sequenceStatus": "loading",
|
||||
"specialExamsEnabledWaffleFlag": false,
|
||||
},
|
||||
"models": Object {
|
||||
"courseHomeMeta": Object {
|
||||
@@ -32,6 +30,7 @@ Object {
|
||||
},
|
||||
"id": "course-v1:edX+DemoX+Demo_Course_1",
|
||||
"isEnrolled": false,
|
||||
"isMasquerading": false,
|
||||
"isSelfPaced": false,
|
||||
"isStaff": false,
|
||||
"number": "DemoX",
|
||||
@@ -71,6 +70,7 @@ Object {
|
||||
},
|
||||
],
|
||||
"title": "Demonstration Course",
|
||||
"userTimezone": "UTC",
|
||||
"verifiedMode": Object {
|
||||
"currencySymbol": "$",
|
||||
"price": 10,
|
||||
@@ -295,7 +295,6 @@ Object {
|
||||
"hasEnded": false,
|
||||
"id": "course-v1:edX+DemoX+Demo_Course_1",
|
||||
"learnerIsFullAccess": true,
|
||||
"userTimezone": "America/New_York",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -318,10 +317,8 @@ Object {
|
||||
"courseware": Object {
|
||||
"courseId": null,
|
||||
"courseStatus": "loading",
|
||||
"proctoredExamsEnabledWaffleFlag": false,
|
||||
"sequenceId": null,
|
||||
"sequenceStatus": "loading",
|
||||
"specialExamsEnabledWaffleFlag": false,
|
||||
},
|
||||
"models": Object {
|
||||
"courseHomeMeta": Object {
|
||||
@@ -337,6 +334,7 @@ Object {
|
||||
},
|
||||
"id": "course-v1:edX+DemoX+Demo_Course_1",
|
||||
"isEnrolled": false,
|
||||
"isMasquerading": false,
|
||||
"isSelfPaced": false,
|
||||
"isStaff": false,
|
||||
"number": "DemoX",
|
||||
@@ -376,6 +374,7 @@ Object {
|
||||
},
|
||||
],
|
||||
"title": "Demonstration Course",
|
||||
"userTimezone": "UTC",
|
||||
"verifiedMode": Object {
|
||||
"currencySymbol": "$",
|
||||
"price": 10,
|
||||
@@ -442,11 +441,6 @@ Object {
|
||||
"title": "Bookmarks",
|
||||
"url": "https://example.com/bookmarks",
|
||||
},
|
||||
Object {
|
||||
"analyticsId": "edx.tool.verified_upgrade",
|
||||
"title": "Upgrade to Verified",
|
||||
"url": "https://example.com/upgrade",
|
||||
},
|
||||
],
|
||||
"datesBannerInfo": Object {
|
||||
"contentTypeGatingEnabled": false,
|
||||
@@ -455,7 +449,6 @@ Object {
|
||||
},
|
||||
"datesWidget": Object {
|
||||
"courseDateBlocks": Array [],
|
||||
"userTimezone": "UTC",
|
||||
},
|
||||
"enrollAlert": Object {
|
||||
"canEnroll": true,
|
||||
@@ -504,10 +497,8 @@ Object {
|
||||
"courseware": Object {
|
||||
"courseId": null,
|
||||
"courseStatus": "loading",
|
||||
"proctoredExamsEnabledWaffleFlag": false,
|
||||
"sequenceId": null,
|
||||
"sequenceStatus": "loading",
|
||||
"specialExamsEnabledWaffleFlag": false,
|
||||
},
|
||||
"models": Object {
|
||||
"courseHomeMeta": Object {
|
||||
@@ -523,6 +514,7 @@ Object {
|
||||
},
|
||||
"id": "course-v1:edX+DemoX+Demo_Course_1",
|
||||
"isEnrolled": false,
|
||||
"isMasquerading": false,
|
||||
"isSelfPaced": false,
|
||||
"isStaff": false,
|
||||
"number": "DemoX",
|
||||
@@ -562,6 +554,7 @@ Object {
|
||||
},
|
||||
],
|
||||
"title": "Demonstration Course",
|
||||
"userTimezone": "UTC",
|
||||
"verifiedMode": Object {
|
||||
"currencySymbol": "$",
|
||||
"price": 10,
|
||||
@@ -571,6 +564,7 @@ Object {
|
||||
},
|
||||
"progress": Object {
|
||||
"course-v1:edX+DemoX+Demo_Course_1": Object {
|
||||
"accessExpiration": null,
|
||||
"certificateData": Object {},
|
||||
"completionSummary": Object {
|
||||
"completeCount": 1,
|
||||
|
||||
@@ -98,6 +98,7 @@ function normalizeCourseHomeCourseMetadata(metadata) {
|
||||
title: tab.title,
|
||||
url: tab.url,
|
||||
})),
|
||||
isMasquerading: data.originalUserIsStaff && !data.isStaff,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -179,7 +180,7 @@ export function normalizeOutlineBlocks(courseId, blocks) {
|
||||
}
|
||||
|
||||
export async function getCourseHomeCourseMetadata(courseId) {
|
||||
let url = `${getConfig().LMS_BASE_URL}/api/course_home/v1/course_metadata/${courseId}`;
|
||||
let url = `${getConfig().LMS_BASE_URL}/api/course_home/course_metadata/${courseId}`;
|
||||
url = appendBrowserTimezoneToUrl(url);
|
||||
const { data } = await getAuthenticatedHttpClient().get(url);
|
||||
return normalizeCourseHomeCourseMetadata(data);
|
||||
@@ -191,7 +192,7 @@ export async function getCourseHomeCourseMetadata(courseId) {
|
||||
// import './__factories__';
|
||||
export async function getDatesTabData(courseId) {
|
||||
// return camelCaseObject(Factory.build('datesTabData'));
|
||||
const url = `${getConfig().LMS_BASE_URL}/api/course_home/v1/dates/${courseId}`;
|
||||
const url = `${getConfig().LMS_BASE_URL}/api/course_home/dates/${courseId}`;
|
||||
try {
|
||||
const { data } = await getAuthenticatedHttpClient().get(url);
|
||||
return camelCaseObject(data);
|
||||
@@ -211,7 +212,7 @@ export async function getDatesTabData(courseId) {
|
||||
}
|
||||
|
||||
export async function getProgressTabData(courseId, targetUserId) {
|
||||
let url = `${getConfig().LMS_BASE_URL}/api/course_home/v1/progress/${courseId}`;
|
||||
let url = `${getConfig().LMS_BASE_URL}/api/course_home/progress/${courseId}`;
|
||||
|
||||
// If targetUserId is passed in, we will get the progress page data
|
||||
// for the user with the provided id, rather than the requesting user.
|
||||
@@ -312,7 +313,7 @@ export function getTimeOffsetMillis(headerDate, requestTime, responseTime) {
|
||||
}
|
||||
|
||||
export async function getOutlineTabData(courseId) {
|
||||
const url = `${getConfig().LMS_BASE_URL}/api/course_home/v1/outline/${courseId}`;
|
||||
const url = `${getConfig().LMS_BASE_URL}/api/course_home/outline/${courseId}`;
|
||||
let { tabData } = {};
|
||||
let requestTime = Date.now();
|
||||
let responseTime = requestTime;
|
||||
@@ -386,12 +387,12 @@ export async function postCourseDeadlines(courseId, model) {
|
||||
}
|
||||
|
||||
export async function postCourseGoals(courseId, goalKey) {
|
||||
const url = new URL(`${getConfig().LMS_BASE_URL}/api/course_home/v1/save_course_goal`);
|
||||
const url = new URL(`${getConfig().LMS_BASE_URL}/api/course_home/save_course_goal`);
|
||||
return getAuthenticatedHttpClient().post(url.href, { course_id: courseId, goal_key: goalKey });
|
||||
}
|
||||
|
||||
export async function postDismissWelcomeMessage(courseId) {
|
||||
const url = new URL(`${getConfig().LMS_BASE_URL}/api/course_home/v1/dismiss_welcome_message`);
|
||||
const url = new URL(`${getConfig().LMS_BASE_URL}/api/course_home/dismiss_welcome_message`);
|
||||
await getAuthenticatedHttpClient().post(url.href, { course_id: courseId });
|
||||
}
|
||||
|
||||
@@ -407,3 +408,9 @@ export async function executePostFromPostEvent(postData, researchEventData) {
|
||||
research_event_data: researchEventData,
|
||||
});
|
||||
}
|
||||
|
||||
export async function unsubscribeFromCourseGoal(token) {
|
||||
const url = new URL(`${getConfig().LMS_BASE_URL}/api/course_home/unsubscribe_from_course_goal/${token}`);
|
||||
return getAuthenticatedHttpClient().post(url.href)
|
||||
.then(res => camelCaseObject(res));
|
||||
}
|
||||
|
||||
223
src/course-home/data/pact-tests/lmsPact.test.jsx
Normal file
223
src/course-home/data/pact-tests/lmsPact.test.jsx
Normal file
@@ -0,0 +1,223 @@
|
||||
import { Pact, Matchers } from '@pact-foundation/pact';
|
||||
import path from 'path';
|
||||
import { mergeConfig, getConfig } from '@edx/frontend-platform';
|
||||
|
||||
import {
|
||||
getCourseHomeCourseMetadata,
|
||||
getDatesTabData,
|
||||
} from '../api';
|
||||
|
||||
import { initializeMockApp } from '../../../setupTest';
|
||||
import {
|
||||
courseId, dateRegex, opaqueKeysRegex, dateTypeRegex,
|
||||
} from '../../../pacts/constants';
|
||||
|
||||
const {
|
||||
somethingLike: like, term, boolean, string, eachLike,
|
||||
} = Matchers;
|
||||
const provider = new Pact({
|
||||
consumer: 'frontend-app-learning',
|
||||
provider: 'lms',
|
||||
log: path.resolve(process.cwd(), 'src/course-home/data/pact-tests/logs', 'pact.log'),
|
||||
dir: path.resolve(process.cwd(), 'src/pacts'),
|
||||
pactfileWriteMode: 'merge',
|
||||
logLevel: 'DEBUG',
|
||||
cors: true,
|
||||
});
|
||||
|
||||
describe('Course Home Service', () => {
|
||||
beforeAll(async () => {
|
||||
initializeMockApp();
|
||||
await provider
|
||||
.setup()
|
||||
.then((options) => mergeConfig({
|
||||
LMS_BASE_URL: `http://localhost:${options.port}`,
|
||||
}, 'Custom app config for pact tests'));
|
||||
});
|
||||
|
||||
afterEach(() => provider.verify());
|
||||
afterAll(() => provider.finalize());
|
||||
describe('When a request to fetch tab is made', () => {
|
||||
it('returns tab data for a course_id', async () => {
|
||||
await provider.addInteraction({
|
||||
state: `Tab data exists for course_id ${courseId}`,
|
||||
uponReceiving: 'a request to fetch tab',
|
||||
withRequest: {
|
||||
method: 'GET',
|
||||
path: `/api/course_home/course_metadata/${courseId}`,
|
||||
},
|
||||
willRespondWith: {
|
||||
status: 200,
|
||||
body: {
|
||||
can_show_upgrade_sock: boolean(false),
|
||||
verified_mode: like({
|
||||
access_expiration_date: null,
|
||||
currency: 'USD',
|
||||
currency_symbol: '$',
|
||||
price: 149,
|
||||
sku: '8CF08E5',
|
||||
upgrade_url: `${getConfig().ECOMMERCE_BASE_URL}/basket/add/?sku=8CF08E5`,
|
||||
}),
|
||||
can_load_courseware: boolean(true),
|
||||
celebrations: like({
|
||||
first_section: false,
|
||||
streak_length_to_celebrate: null,
|
||||
streak_discount_enabled: false,
|
||||
}),
|
||||
course_access: {
|
||||
has_access: boolean(true),
|
||||
error_code: null,
|
||||
developer_message: null,
|
||||
user_message: null,
|
||||
additional_context_user_message: null,
|
||||
user_fragment: null,
|
||||
},
|
||||
course_id: term({
|
||||
generate: 'course-v1:edX+DemoX+Demo_Course',
|
||||
matcher: opaqueKeysRegex,
|
||||
}),
|
||||
is_enrolled: boolean(true),
|
||||
is_self_paced: boolean(false),
|
||||
is_staff: boolean(true),
|
||||
number: string('DemoX'),
|
||||
org: string('edX'),
|
||||
original_user_is_staff: boolean(true),
|
||||
start: term({
|
||||
generate: '2013-02-05T05:00:00Z',
|
||||
matcher: dateRegex,
|
||||
}),
|
||||
tabs: eachLike({
|
||||
tab_id: 'courseware',
|
||||
title: 'Course',
|
||||
url: `${getConfig().BASE_URL}/course/course-v1:edX+DemoX+Demo_Course/home`,
|
||||
}),
|
||||
title: string('Demonstration Course'),
|
||||
username: string('edx'),
|
||||
},
|
||||
},
|
||||
});
|
||||
const normalizedTabData = {
|
||||
canShowUpgradeSock: false,
|
||||
verifiedMode: {
|
||||
accessExpirationDate: null,
|
||||
currency: 'USD',
|
||||
currencySymbol: '$',
|
||||
price: 149,
|
||||
sku: '8CF08E5',
|
||||
upgradeUrl: `${getConfig().ECOMMERCE_BASE_URL}/basket/add/?sku=8CF08E5`,
|
||||
},
|
||||
canLoadCourseware: true,
|
||||
celebrations: {
|
||||
firstSection: false,
|
||||
streakLengthToCelebrate: null,
|
||||
streakDiscountEnabled: false,
|
||||
},
|
||||
courseAccess: {
|
||||
hasAccess: true,
|
||||
errorCode: null,
|
||||
developerMessage: null,
|
||||
userMessage: null,
|
||||
additionalContextUserMessage: null,
|
||||
userFragment: null,
|
||||
},
|
||||
courseId: 'course-v1:edX+DemoX+Demo_Course',
|
||||
isEnrolled: true,
|
||||
isMasquerading: false,
|
||||
isSelfPaced: false,
|
||||
isStaff: true,
|
||||
number: 'DemoX',
|
||||
org: 'edX',
|
||||
originalUserIsStaff: true,
|
||||
start: '2013-02-05T05:00:00Z',
|
||||
tabs: [
|
||||
{
|
||||
slug: 'outline',
|
||||
title: 'Course',
|
||||
url: `${getConfig().BASE_URL}/course/course-v1:edX+DemoX+Demo_Course/home`,
|
||||
},
|
||||
],
|
||||
title: 'Demonstration Course',
|
||||
username: 'edx',
|
||||
};
|
||||
const response = await getCourseHomeCourseMetadata(courseId);
|
||||
expect(response).toBeTruthy();
|
||||
expect(response).toEqual(normalizedTabData);
|
||||
});
|
||||
});
|
||||
|
||||
describe('When a request to fetch dates tab is made', () => {
|
||||
it('returns course date blocks for a course_id', async () => {
|
||||
await provider.addInteraction({
|
||||
state: `course date blocks exist for course_id ${courseId}`,
|
||||
uponReceiving: 'a request to fetch dates tab',
|
||||
withRequest: {
|
||||
method: 'GET',
|
||||
path: `/api/course_home/dates/${courseId}`,
|
||||
},
|
||||
willRespondWith: {
|
||||
status: 200,
|
||||
body: {
|
||||
dates_banner_info: like({
|
||||
missed_deadlines: false,
|
||||
content_type_gating_enabled: false,
|
||||
missed_gated_content: false,
|
||||
verified_upgrade_link: `${getConfig().ECOMMERCE_BASE_URL}/basket/add/?sku=8CF08E5`,
|
||||
}),
|
||||
course_date_blocks: eachLike({
|
||||
assignment_type: null,
|
||||
complete: null,
|
||||
date: term({
|
||||
generate: '2013-02-05T05:00:00Z',
|
||||
matcher: dateRegex,
|
||||
}),
|
||||
date_type: term({
|
||||
generate: 'verified-upgrade-deadline',
|
||||
matcher: dateTypeRegex,
|
||||
}),
|
||||
description: 'You are still eligible to upgrade to a Verified Certificate! Pursue it to highlight the knowledge and skills you gain in this course.',
|
||||
learner_has_access: true,
|
||||
link: `${getConfig().ECOMMERCE_BASE_URL}/basket/add/?sku=8CF08E5`,
|
||||
link_text: 'Upgrade to Verified Certificate',
|
||||
title: 'Verification Upgrade Deadline',
|
||||
extra_info: null,
|
||||
first_component_block_id: '',
|
||||
}),
|
||||
has_ended: boolean(false),
|
||||
learner_is_full_access: boolean(true),
|
||||
user_timezone: null,
|
||||
},
|
||||
},
|
||||
});
|
||||
const camelCaseResponse = {
|
||||
datesBannerInfo: {
|
||||
missedDeadlines: false,
|
||||
contentTypeGatingEnabled: false,
|
||||
missedGatedContent: false,
|
||||
verifiedUpgradeLink: `${getConfig().ECOMMERCE_BASE_URL}/basket/add/?sku=8CF08E5`,
|
||||
},
|
||||
courseDateBlocks: [
|
||||
{
|
||||
assignmentType: null,
|
||||
complete: null,
|
||||
date: '2013-02-05T05:00:00Z',
|
||||
dateType: 'verified-upgrade-deadline',
|
||||
description: 'You are still eligible to upgrade to a Verified Certificate! Pursue it to highlight the knowledge and skills you gain in this course.',
|
||||
learnerHasAccess: true,
|
||||
link: `${getConfig().ECOMMERCE_BASE_URL}/basket/add/?sku=8CF08E5`,
|
||||
linkText: 'Upgrade to Verified Certificate',
|
||||
title: 'Verification Upgrade Deadline',
|
||||
extraInfo: null,
|
||||
firstComponentBlockId: '',
|
||||
},
|
||||
],
|
||||
hasEnded: false,
|
||||
learnerIsFullAccess: true,
|
||||
userTimezone: null,
|
||||
};
|
||||
|
||||
const response = await getDatesTabData(courseId);
|
||||
expect(response).toBeTruthy();
|
||||
expect(response).toEqual(camelCaseResponse);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -18,7 +18,7 @@ const axiosMock = new MockAdapter(getAuthenticatedHttpClient());
|
||||
describe('Data layer integration tests', () => {
|
||||
const courseHomeMetadata = Factory.build('courseHomeMetadata');
|
||||
const { id: courseId } = courseHomeMetadata;
|
||||
let courseMetadataUrl = `${getConfig().LMS_BASE_URL}/api/course_home/v1/course_metadata/${courseId}`;
|
||||
let courseMetadataUrl = `${getConfig().LMS_BASE_URL}/api/course_home/course_metadata/${courseId}`;
|
||||
courseMetadataUrl = appendBrowserTimezoneToUrl(courseMetadataUrl);
|
||||
|
||||
let store;
|
||||
@@ -31,7 +31,7 @@ describe('Data layer integration tests', () => {
|
||||
});
|
||||
|
||||
describe('Test fetchDatesTab', () => {
|
||||
const datesBaseUrl = `${getConfig().LMS_BASE_URL}/api/course_home/v1/dates`;
|
||||
const datesBaseUrl = `${getConfig().LMS_BASE_URL}/api/course_home/dates`;
|
||||
|
||||
it('Should fail to fetch if error occurs', async () => {
|
||||
axiosMock.onGet(courseMetadataUrl).networkError();
|
||||
@@ -60,7 +60,7 @@ describe('Data layer integration tests', () => {
|
||||
});
|
||||
|
||||
describe('Test fetchOutlineTab', () => {
|
||||
const outlineBaseUrl = `${getConfig().LMS_BASE_URL}/api/course_home/v1/outline`;
|
||||
const outlineBaseUrl = `${getConfig().LMS_BASE_URL}/api/course_home/outline`;
|
||||
|
||||
it('Should result in fetch failure if error occurs', async () => {
|
||||
axiosMock.onGet(courseMetadataUrl).networkError();
|
||||
@@ -89,7 +89,7 @@ describe('Data layer integration tests', () => {
|
||||
});
|
||||
|
||||
describe('Test fetchProgressTab', () => {
|
||||
const progressBaseUrl = `${getConfig().LMS_BASE_URL}/api/course_home/v1/progress`;
|
||||
const progressBaseUrl = `${getConfig().LMS_BASE_URL}/api/course_home/progress`;
|
||||
|
||||
it('Should result in fetch failure if error occurs', async () => {
|
||||
axiosMock.onGet(courseMetadataUrl).networkError();
|
||||
@@ -133,7 +133,7 @@ describe('Data layer integration tests', () => {
|
||||
|
||||
describe('Test saveCourseGoal', () => {
|
||||
it('Should save course goal', async () => {
|
||||
const goalUrl = `${getConfig().LMS_BASE_URL}/api/course_home/v1/save_course_goal`;
|
||||
const goalUrl = `${getConfig().LMS_BASE_URL}/api/course_home/save_course_goal`;
|
||||
axiosMock.onPost(goalUrl).reply(200, {});
|
||||
|
||||
await thunks.saveCourseGoal(courseId, 'unsure');
|
||||
@@ -164,7 +164,7 @@ describe('Data layer integration tests', () => {
|
||||
|
||||
describe('Test dismissWelcomeMessage', () => {
|
||||
it('Should dismiss welcome message', async () => {
|
||||
const dismissUrl = `${getConfig().LMS_BASE_URL}/api/course_home/v1/dismiss_welcome_message`;
|
||||
const dismissUrl = `${getConfig().LMS_BASE_URL}/api/course_home/dismiss_welcome_message`;
|
||||
axiosMock.onPost(dismissUrl).reply(201);
|
||||
|
||||
await executeThunk(thunks.dismissWelcomeMessage(courseId), store.dispatch);
|
||||
|
||||
@@ -43,11 +43,11 @@ describe('DatesTab', () => {
|
||||
});
|
||||
|
||||
const datesTabData = Factory.build('datesTabData');
|
||||
let courseMetadata = Factory.build('courseHomeMetadata');
|
||||
let courseMetadata = Factory.build('courseHomeMetadata', { user_timezone: 'America/New_York' });
|
||||
const { id: courseId } = courseMetadata;
|
||||
|
||||
const datesUrl = `${getConfig().LMS_BASE_URL}/api/course_home/v1/dates/${courseId}`;
|
||||
let courseMetadataUrl = `${getConfig().LMS_BASE_URL}/api/course_home/v1/course_metadata/${courseId}`;
|
||||
const datesUrl = `${getConfig().LMS_BASE_URL}/api/course_home/dates/${courseId}`;
|
||||
let courseMetadataUrl = `${getConfig().LMS_BASE_URL}/api/course_home/course_metadata/${courseId}`;
|
||||
courseMetadataUrl = appendBrowserTimezoneToUrl(courseMetadataUrl);
|
||||
|
||||
function setMetadata(attributes, options) {
|
||||
|
||||
@@ -29,10 +29,10 @@ function Day({
|
||||
const {
|
||||
courseId,
|
||||
} = useSelector(state => state.courseHome);
|
||||
|
||||
const {
|
||||
userTimezone,
|
||||
} = useModel('dates', courseId);
|
||||
} = useModel('courseHomeMeta', courseId);
|
||||
|
||||
const timezoneFormatArgs = userTimezone ? { timeZone: userTimezone } : {};
|
||||
|
||||
const { color, badges } = getBadgeListAndColor(date, intl, null, items);
|
||||
|
||||
52
src/course-home/goal-unsubscribe/GoalUnsubscribe.jsx
Normal file
52
src/course-home/goal-unsubscribe/GoalUnsubscribe.jsx
Normal file
@@ -0,0 +1,52 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import { Header } from '../../course-header';
|
||||
import PageLoading from '../../generic/PageLoading';
|
||||
import { unsubscribeFromCourseGoal } from '../data/api';
|
||||
|
||||
import messages from './messages';
|
||||
import ResultPage from './ResultPage';
|
||||
|
||||
function GoalUnsubscribe({ intl }) {
|
||||
const { token } = useParams();
|
||||
const [error, setError] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [data, setData] = useState({});
|
||||
|
||||
// We don't need to bother with redux for this simple page. We're not sharing state with other pages at all.
|
||||
useEffect(() => {
|
||||
unsubscribeFromCourseGoal(token)
|
||||
.then(
|
||||
(result) => {
|
||||
setIsLoading(false);
|
||||
setData(result.data);
|
||||
},
|
||||
() => {
|
||||
setIsLoading(false);
|
||||
setError(true);
|
||||
},
|
||||
);
|
||||
}, []); // deps=[] to only run once
|
||||
|
||||
return (
|
||||
<>
|
||||
<Header showUserDropdown={false} />
|
||||
<main id="main-content" className="container my-5 text-center">
|
||||
{isLoading && (
|
||||
<PageLoading srMessage={`${intl.formatMessage(messages.loading)}`} />
|
||||
)}
|
||||
{!isLoading && (
|
||||
<ResultPage error={error} courseTitle={data.courseTitle} />
|
||||
)}
|
||||
</main>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
GoalUnsubscribe.propTypes = {
|
||||
intl: intlShape.isRequired,
|
||||
};
|
||||
|
||||
export default injectIntl(GoalUnsubscribe);
|
||||
62
src/course-home/goal-unsubscribe/GoalUnsubscribe.test.jsx
Normal file
62
src/course-home/goal-unsubscribe/GoalUnsubscribe.test.jsx
Normal file
@@ -0,0 +1,62 @@
|
||||
import React from 'react';
|
||||
import { Route } from 'react-router';
|
||||
import MockAdapter from 'axios-mock-adapter';
|
||||
import { getConfig, history } from '@edx/frontend-platform';
|
||||
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
|
||||
import { AppProvider } from '@edx/frontend-platform/react';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
|
||||
import GoalUnsubscribe from './GoalUnsubscribe';
|
||||
import { act, initializeMockApp } from '../../setupTest';
|
||||
import initializeStore from '../../store';
|
||||
import { UserMessagesProvider } from '../../generic/user-messages';
|
||||
|
||||
initializeMockApp();
|
||||
jest.mock('@edx/frontend-platform/analytics');
|
||||
|
||||
describe('GoalUnsubscribe', () => {
|
||||
let axiosMock;
|
||||
let store;
|
||||
let component;
|
||||
const unsubscribeUrl = `${getConfig().LMS_BASE_URL}/api/course_home/unsubscribe_from_course_goal/TOKEN`;
|
||||
|
||||
beforeEach(() => {
|
||||
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
|
||||
store = initializeStore();
|
||||
component = (
|
||||
<AppProvider store={store}>
|
||||
<UserMessagesProvider>
|
||||
<Route path="/goal-unsubscribe/:token" component={GoalUnsubscribe} />
|
||||
</UserMessagesProvider>
|
||||
</AppProvider>
|
||||
);
|
||||
history.push('/goal-unsubscribe/TOKEN'); // so we can pull token from url
|
||||
});
|
||||
|
||||
it('starts with a spinner', () => {
|
||||
render(component);
|
||||
expect(screen.getByRole('status')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('loads a real token', async () => {
|
||||
const response = { course_title: 'My Sample Course' };
|
||||
axiosMock.onPost(unsubscribeUrl).reply(200, response);
|
||||
await act(async () => render(component));
|
||||
|
||||
expect(screen.getByText('You’ve unsubscribed from goal reminders')).toBeInTheDocument();
|
||||
expect(screen.getByText(/your goal for My Sample Course/)).toBeInTheDocument();
|
||||
expect(screen.getByRole('link', { name: 'Go to dashboard' }))
|
||||
.toHaveAttribute('href', 'http://localhost:18000/dashboard');
|
||||
});
|
||||
|
||||
it('loads a bad token with an error page', async () => {
|
||||
axiosMock.onPost(unsubscribeUrl).reply(404, {});
|
||||
await act(async () => render(component));
|
||||
|
||||
expect(screen.getByText('Something went wrong')).toBeInTheDocument();
|
||||
expect(screen.getByRole('link', { name: 'Go to dashboard' }))
|
||||
.toHaveAttribute('href', 'http://localhost:18000/dashboard');
|
||||
expect(screen.getByRole('link', { name: 'contact support' }))
|
||||
.toHaveAttribute('href', 'http://localhost:18000/contact');
|
||||
});
|
||||
});
|
||||
58
src/course-home/goal-unsubscribe/ResultPage.jsx
Normal file
58
src/course-home/goal-unsubscribe/ResultPage.jsx
Normal file
@@ -0,0 +1,58 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import { FormattedMessage, injectIntl, intlShape } from '@edx/frontend-platform/i18n';
|
||||
import { Button, Hyperlink } from '@edx/paragon';
|
||||
|
||||
import messages from './messages';
|
||||
import { ReactComponent as UnsubscribeIcon } from './unsubscribe.svg';
|
||||
|
||||
function ResultPage({ courseTitle, error, intl }) {
|
||||
const errorDescription = (
|
||||
<FormattedMessage
|
||||
id="learning.goals.unsubscribe.errorDescription"
|
||||
defaultMessage="We were unable to unsubscribe you from goal reminder emails. Please try again later or {contactSupport} for help."
|
||||
values={{
|
||||
contactSupport: (
|
||||
<Hyperlink
|
||||
className="text-reset"
|
||||
style={{ textDecoration: 'underline' }}
|
||||
destination={`${getConfig().CONTACT_URL}`}
|
||||
>
|
||||
{intl.formatMessage(messages.contactSupport)}
|
||||
</Hyperlink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
const header = error
|
||||
? intl.formatMessage(messages.errorHeader)
|
||||
: intl.formatMessage(messages.header);
|
||||
const description = error
|
||||
? errorDescription
|
||||
: intl.formatMessage(messages.description, { courseTitle });
|
||||
|
||||
return (
|
||||
<>
|
||||
<UnsubscribeIcon className="text-primary" alt="" />
|
||||
<div role="heading" aria-level="1" className="h2">{header}</div>
|
||||
<div>{description}</div>
|
||||
<Button variant="brand" href={`${getConfig().LMS_BASE_URL}/dashboard`} className="mt-4">
|
||||
{intl.formatMessage(messages.goToDashboard)}
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
ResultPage.defaultProps = {
|
||||
courseTitle: null,
|
||||
error: false,
|
||||
};
|
||||
|
||||
ResultPage.propTypes = {
|
||||
courseTitle: PropTypes.string,
|
||||
error: PropTypes.bool,
|
||||
intl: intlShape.isRequired,
|
||||
};
|
||||
|
||||
export default injectIntl(ResultPage);
|
||||
3
src/course-home/goal-unsubscribe/index.jsx
Normal file
3
src/course-home/goal-unsubscribe/index.jsx
Normal file
@@ -0,0 +1,3 @@
|
||||
import GoalUnsubscribe from './GoalUnsubscribe';
|
||||
|
||||
export default GoalUnsubscribe;
|
||||
30
src/course-home/goal-unsubscribe/messages.js
Normal file
30
src/course-home/goal-unsubscribe/messages.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import { defineMessages } from '@edx/frontend-platform/i18n';
|
||||
|
||||
const messages = defineMessages({
|
||||
contactSupport: {
|
||||
id: 'learning.goals.unsubscribe.contact',
|
||||
defaultMessage: 'contact support',
|
||||
},
|
||||
description: {
|
||||
id: 'learning.goals.unsubscribe.description',
|
||||
defaultMessage: 'You will no longer receive email reminders about your goal for {courseTitle}.',
|
||||
},
|
||||
errorHeader: {
|
||||
id: 'learning.goals.unsubscribe.errorHeader',
|
||||
defaultMessage: 'Something went wrong',
|
||||
},
|
||||
goToDashboard: {
|
||||
id: 'learning.goals.unsubscribe.goToDashboard',
|
||||
defaultMessage: 'Go to dashboard',
|
||||
},
|
||||
header: {
|
||||
id: 'learning.goals.unsubscribe.header',
|
||||
defaultMessage: 'You’ve unsubscribed from goal reminders',
|
||||
},
|
||||
loading: {
|
||||
id: 'learning.goals.unsubscribe.loading',
|
||||
defaultMessage: 'Unsubscribing…',
|
||||
},
|
||||
});
|
||||
|
||||
export default messages;
|
||||
5
src/course-home/goal-unsubscribe/unsubscribe.svg
Normal file
5
src/course-home/goal-unsubscribe/unsubscribe.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg width="167" height="153" viewBox="0 0 167 153" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M140.25 25.5H12.75V127.5H140.25V25.5ZM127.5 46L76.5 77.875L25.5 46V38.25L76.5 70.125L127.5 38.25V46Z" fill="currentColor"/>
|
||||
<circle cx="134" cy="39" r="33" transform="rotate(-90 134 39)" fill="white"/>
|
||||
<path d="M134 11C118.544 11 106 23.544 106 39C106 54.456 118.544 67 134 67C149.456 67 162 54.456 162 39C162 23.544 149.456 11 134 11ZM134 61.4C121.624 61.4 111.6 51.376 111.6 39C111.6 33.82 113.364 29.06 116.332 25.28L147.72 56.668C143.94 59.636 139.18 61.4 134 61.4ZM151.668 52.72L120.28 21.332C124.06 18.364 128.82 16.6 134 16.6C146.376 16.6 156.4 26.624 156.4 39C156.4 44.18 154.636 48.94 151.668 52.72Z" fill="#D23228"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 743 B |
@@ -1,6 +1,7 @@
|
||||
import React, { useState } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { sendTrackEvent, sendTrackingLogEvent } from '@edx/frontend-platform/analytics';
|
||||
import { getAuthenticatedUser } from '@edx/frontend-platform/auth';
|
||||
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import { Button, Toast } from '@edx/paragon';
|
||||
@@ -17,11 +18,10 @@ import Section from './Section';
|
||||
import ShiftDatesAlert from '../suggested-schedule-messaging/ShiftDatesAlert';
|
||||
import UpdateGoalSelector from './widgets/UpdateGoalSelector';
|
||||
import UpgradeNotification from '../../generic/upgrade-notification/UpgradeNotification';
|
||||
import { useAccessExpirationAlertMasquerade } from '../../alerts/access-expiration-alert';
|
||||
import UpgradeToShiftDatesAlert from '../suggested-schedule-messaging/UpgradeToShiftDatesAlert';
|
||||
import useCertificateAvailableAlert from './alerts/certificate-status-alert';
|
||||
import useCourseEndAlert from './alerts/course-end-alert';
|
||||
import useCourseStartAlert from './alerts/course-start-alert';
|
||||
import useCourseStartAlert from '../../alerts/course-start-alert';
|
||||
import usePrivateCourseAlert from './alerts/private-course-alert';
|
||||
import useScheduledContentAlert from './alerts/scheduled-content-alert';
|
||||
import { useModel } from '../../generic/model-store';
|
||||
@@ -42,6 +42,7 @@ function OutlineTab({ intl }) {
|
||||
org,
|
||||
title,
|
||||
username,
|
||||
userTimezone,
|
||||
} = useModel('courseHomeMeta', courseId);
|
||||
|
||||
const {
|
||||
@@ -57,7 +58,6 @@ function OutlineTab({ intl }) {
|
||||
datesBannerInfo,
|
||||
datesWidget: {
|
||||
courseDateBlocks,
|
||||
userTimezone,
|
||||
},
|
||||
resumeCourse: {
|
||||
hasVisitedCourse,
|
||||
@@ -86,7 +86,6 @@ function OutlineTab({ intl }) {
|
||||
};
|
||||
|
||||
// Below the course title alerts (appearing in the order listed here)
|
||||
const accessExpirationAlertMasquerade = useAccessExpirationAlertMasquerade(accessExpiration, userTimezone, 'outline-course-alerts');
|
||||
const courseStartAlert = useCourseStartAlert(courseId);
|
||||
const courseEndAlert = useCourseEndAlert(courseId);
|
||||
const certificateAvailableAlert = useCertificateAvailableAlert(courseId);
|
||||
@@ -107,9 +106,19 @@ function OutlineTab({ intl }) {
|
||||
});
|
||||
};
|
||||
|
||||
const isEnterpriseUser = () => {
|
||||
const authenticatedUser = getAuthenticatedUser();
|
||||
const userRoleNames = authenticatedUser ? authenticatedUser.roles.map(role => role.split(':')[0]) : [];
|
||||
|
||||
return userRoleNames.includes('enterprise_learner');
|
||||
};
|
||||
|
||||
/** [[MM-P2P] Experiment */
|
||||
const MMP2P = initHomeMMP2P(courseId);
|
||||
|
||||
/** show post enrolment survey to only B2C learners */
|
||||
const learnerType = isEnterpriseUser() ? 'enterprise_learner' : 'b2c_learner';
|
||||
|
||||
return (
|
||||
<>
|
||||
<Toast
|
||||
@@ -119,7 +128,7 @@ function OutlineTab({ intl }) {
|
||||
>
|
||||
{goalToastHeader}
|
||||
</Toast>
|
||||
<div className="row w-100 mx-0 my-3 justify-content-between">
|
||||
<div data-learner-type={learnerType} className="row w-100 mx-0 my-3 justify-content-between">
|
||||
<div className="col-12 col-sm-auto p-0">
|
||||
<div role="heading" aria-level="1" className="h2">{title}</div>
|
||||
</div>
|
||||
@@ -150,7 +159,6 @@ function OutlineTab({ intl }) {
|
||||
topic="outline-course-alerts"
|
||||
className="mb-3"
|
||||
customAlerts={{
|
||||
...accessExpirationAlertMasquerade,
|
||||
...certificateAvailableAlert,
|
||||
...courseEndAlert,
|
||||
...courseStartAlert,
|
||||
|
||||
@@ -16,6 +16,7 @@ import * as thunks from '../data/thunks';
|
||||
import initializeStore from '../../store';
|
||||
import { CERT_STATUS_TYPE } from './alerts/certificate-status-alert/CertificateStatusAlert';
|
||||
import OutlineTab from './OutlineTab';
|
||||
import LoadedTabPage from '../../tab-page/LoadedTabPage';
|
||||
|
||||
initializeMockApp();
|
||||
jest.mock('@edx/frontend-platform/analytics');
|
||||
@@ -24,11 +25,12 @@ describe('Outline Tab', () => {
|
||||
let axiosMock;
|
||||
|
||||
const courseId = 'course-v1:edX+Test+run';
|
||||
let courseMetadataUrl = `${getConfig().LMS_BASE_URL}/api/course_home/v1/course_metadata/${courseId}`;
|
||||
let courseMetadataUrl = `${getConfig().LMS_BASE_URL}/api/course_home/course_metadata/${courseId}`;
|
||||
courseMetadataUrl = appendBrowserTimezoneToUrl(courseMetadataUrl);
|
||||
const enrollmentUrl = `${getConfig().LMS_BASE_URL}/api/enrollment/v1/enrollment`;
|
||||
const goalUrl = `${getConfig().LMS_BASE_URL}/api/course_home/v1/save_course_goal`;
|
||||
const outlineUrl = `${getConfig().LMS_BASE_URL}/api/course_home/v1/outline/${courseId}`;
|
||||
const goalUrl = `${getConfig().LMS_BASE_URL}/api/course_home/save_course_goal`;
|
||||
const masqueradeUrl = `${getConfig().LMS_BASE_URL}/courses/${courseId}/masquerade`;
|
||||
const outlineUrl = `${getConfig().LMS_BASE_URL}/api/course_home/outline/${courseId}`;
|
||||
const proctoringInfoUrl = `${getConfig().LMS_BASE_URL}/api/edx_proctoring/v1/user_onboarding/status?is_learning_mfe=true&course_id=${encodeURIComponent(courseId)}`;
|
||||
|
||||
const store = initializeStore();
|
||||
@@ -57,6 +59,7 @@ describe('Outline Tab', () => {
|
||||
axiosMock.onGet(courseMetadataUrl).reply(200, defaultMetadata);
|
||||
axiosMock.onPost(enrollmentUrl).reply(200, {});
|
||||
axiosMock.onPost(goalUrl).reply(200, { header: 'Success' });
|
||||
axiosMock.onGet(masqueradeUrl).reply(200, { success: true });
|
||||
axiosMock.onGet(outlineUrl).reply(200, defaultTabData);
|
||||
axiosMock.onGet(proctoringInfoUrl).reply(200, {
|
||||
onboarding_status: 'created',
|
||||
@@ -437,35 +440,6 @@ describe('Outline Tab', () => {
|
||||
await fetchAndRender();
|
||||
expect(screen.queryByRole('heading', { name: 'Course Tools' })).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('analytics sent when upgrade link clicked', async () => {
|
||||
await fetchAndRender();
|
||||
expect(screen.getByRole('heading', { name: 'Course Tools' })).toBeInTheDocument();
|
||||
sendTrackEvent.mockClear();
|
||||
sendTrackingLogEvent.mockClear();
|
||||
|
||||
const upgradeLink = screen.getByRole('link', { name: 'Upgrade to Verified' });
|
||||
fireEvent.click(upgradeLink);
|
||||
|
||||
expect(sendTrackEvent).toHaveBeenCalledTimes(1);
|
||||
expect(sendTrackEvent).toHaveBeenCalledWith('edx.bi.ecommerce.upsell_links_clicked', {
|
||||
org_key: 'edX',
|
||||
courserun_key: courseId,
|
||||
linkCategory: '(none)',
|
||||
linkName: 'course_home_course_tools',
|
||||
linkType: 'link',
|
||||
pageName: 'course_home',
|
||||
});
|
||||
|
||||
expect(sendTrackingLogEvent).toHaveBeenCalledTimes(1);
|
||||
expect(sendTrackingLogEvent).toHaveBeenCalledWith('edx.course.tool.accessed', {
|
||||
org_key: 'edX',
|
||||
courserun_key: courseId,
|
||||
course_id: courseId,
|
||||
is_staff: false,
|
||||
tool_name: 'edx.tool.verified_upgrade',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Alert List', () => {
|
||||
@@ -521,32 +495,35 @@ describe('Outline Tab', () => {
|
||||
});
|
||||
|
||||
describe('Access Expiration Alert', () => {
|
||||
it('has special masquerade text', async () => {
|
||||
it('renders page banner on masquerade', async () => {
|
||||
setMetadata({ is_enrolled: true, original_user_is_staff: true });
|
||||
setTabData({
|
||||
access_expiration: {
|
||||
expiration_date: '2020-01-01T12:00:00Z',
|
||||
masquerading_expired_course: true,
|
||||
upgrade_deadline: null,
|
||||
upgrade_url: null,
|
||||
},
|
||||
});
|
||||
await fetchAndRender();
|
||||
const check = await screen.queryByText('This learner does not have access to this course.', { exact: false });
|
||||
expect(check).toBeInTheDocument();
|
||||
await executeThunk(thunks.fetchOutlineTab(courseId), store.dispatch);
|
||||
await act(async () => render(<LoadedTabPage courseId={courseId} activeTabSlug="outline">...</LoadedTabPage>, { store }));
|
||||
const instructorToolbar = await screen.getByTestId('instructor-toolbar');
|
||||
expect(instructorToolbar).toBeInTheDocument();
|
||||
expect(screen.getByText('This learner no longer has access to this course. Their access expired on', { exact: false })).toBeInTheDocument();
|
||||
expect(screen.getByText('1/1/2020')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('does not have special masquerade text', async () => {
|
||||
it('does not render banner when not masquerading', async () => {
|
||||
setMetadata({ is_enrolled: true, original_user_is_staff: true });
|
||||
setTabData({
|
||||
access_expiration: {
|
||||
expiration_date: '2020-01-01T12:00:00Z',
|
||||
masquerading_expired_course: false,
|
||||
upgrade_deadline: null,
|
||||
upgrade_url: null,
|
||||
},
|
||||
});
|
||||
await fetchAndRender();
|
||||
const check = await screen.queryByText('This learner does not have access to this course.', { exact: false });
|
||||
expect(check).not.toBeInTheDocument();
|
||||
await executeThunk(thunks.fetchOutlineTab(courseId), store.dispatch);
|
||||
await act(async () => render(<LoadedTabPage courseId={courseId} activeTabSlug="outline">...</LoadedTabPage>, { store }));
|
||||
const instructorToolbar = await screen.getByTestId('instructor-toolbar');
|
||||
expect(instructorToolbar).toBeInTheDocument();
|
||||
expect(screen.queryByText('This learner no longer has access to this course. Their access expired on', { exact: false })).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -555,16 +532,7 @@ describe('Outline Tab', () => {
|
||||
it('appears several days out', async () => {
|
||||
const startDate = new Date();
|
||||
startDate.setDate(startDate.getDate() + 100);
|
||||
setMetadata({ is_enrolled: true });
|
||||
setTabData({}, {
|
||||
date_blocks: [
|
||||
{
|
||||
date_type: 'course-start-date',
|
||||
date: startDate.toISOString(),
|
||||
title: 'Start',
|
||||
},
|
||||
],
|
||||
});
|
||||
setMetadata({ is_enrolled: true, start: '2999-01-01T00:00:00Z' });
|
||||
await fetchAndRender();
|
||||
const node = await screen.findByText('Course starts', { exact: false });
|
||||
expect(node.textContent).toMatch(/.* on .*/); // several days away uses "on" before date
|
||||
@@ -573,16 +541,7 @@ describe('Outline Tab', () => {
|
||||
it('appears today', async () => {
|
||||
const startDate = new Date();
|
||||
startDate.setHours(startDate.getHours() + 1);
|
||||
setMetadata({ is_enrolled: true });
|
||||
setTabData({}, {
|
||||
date_blocks: [
|
||||
{
|
||||
date_type: 'course-start-date',
|
||||
date: startDate.toISOString(),
|
||||
title: 'Start',
|
||||
},
|
||||
],
|
||||
});
|
||||
setMetadata({ is_enrolled: true, start: startDate });
|
||||
await fetchAndRender();
|
||||
const node = await screen.findByText('Course starts', { exact: false });
|
||||
expect(node.textContent).toMatch(/.* at .*/); // same day uses "at" before date
|
||||
|
||||
@@ -33,9 +33,7 @@ function SequenceLink({
|
||||
title,
|
||||
} = sequence;
|
||||
const {
|
||||
datesWidget: {
|
||||
userTimezone,
|
||||
},
|
||||
userTimezone,
|
||||
} = useModel('outline', courseId);
|
||||
const {
|
||||
canLoadCourseware,
|
||||
|
||||
@@ -39,11 +39,11 @@ function useCertificateStatusAlert(courseId) {
|
||||
const {
|
||||
datesWidget: {
|
||||
courseDateBlocks,
|
||||
userTimezone,
|
||||
},
|
||||
certData,
|
||||
hasEnded,
|
||||
userHasPassingGrade,
|
||||
userTimezone,
|
||||
enrollmentMode,
|
||||
} = useModel('outline', courseId);
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@ export function useCourseEndAlert(courseId) {
|
||||
const {
|
||||
datesWidget: {
|
||||
courseDateBlocks,
|
||||
userTimezone,
|
||||
},
|
||||
userTimezone,
|
||||
} = useModel('outline', courseId);
|
||||
|
||||
const endBlock = courseDateBlocks.find(b => b.dateType === 'course-end-date');
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import { useAlert } from '../../../../generic/user-messages';
|
||||
import { useModel } from '../../../../generic/model-store';
|
||||
|
||||
const CourseStartAlert = React.lazy(() => import('./CourseStartAlert'));
|
||||
|
||||
function useCourseStartAlert(courseId) {
|
||||
const {
|
||||
isEnrolled,
|
||||
} = useModel('courseHomeMeta', courseId);
|
||||
const {
|
||||
datesWidget: {
|
||||
courseDateBlocks,
|
||||
userTimezone,
|
||||
},
|
||||
} = useModel('outline', courseId);
|
||||
|
||||
const startBlock = courseDateBlocks.find(b => b.dateType === 'course-start-date');
|
||||
const delta = startBlock ? new Date(startBlock.date) - new Date() : 0;
|
||||
const isVisible = isEnrolled && startBlock && delta > 0;
|
||||
const payload = {
|
||||
startDate: startBlock && startBlock.date,
|
||||
userTimezone,
|
||||
};
|
||||
|
||||
useAlert(isVisible, {
|
||||
code: 'clientCourseStartAlert',
|
||||
payload: useMemo(() => payload, Object.values(payload).sort()),
|
||||
topic: 'outline-course-alerts',
|
||||
});
|
||||
|
||||
return {
|
||||
clientCourseStartAlert: CourseStartAlert,
|
||||
};
|
||||
}
|
||||
|
||||
export default useCourseStartAlert;
|
||||
@@ -1 +0,0 @@
|
||||
export { default } from './hooks';
|
||||
@@ -216,6 +216,10 @@ const messages = defineMessages({
|
||||
id: 'learning.proctoringPanel.reviewRequirementsButton',
|
||||
defaultMessage: 'Review instructions and system requirements',
|
||||
},
|
||||
proctoringOnboardingButtonPastDue: {
|
||||
id: 'learning.proctoringPanel.onboardingButtonPastDue',
|
||||
defaultMessage: 'Onboarding Past Due',
|
||||
},
|
||||
});
|
||||
|
||||
export default messages;
|
||||
|
||||
@@ -13,11 +13,13 @@ function CourseDates({
|
||||
/** [MM-P2P] Experiment */
|
||||
mmp2p,
|
||||
}) {
|
||||
const {
|
||||
userTimezone,
|
||||
} = useModel('courseHomeMeta', courseId);
|
||||
const {
|
||||
datesWidget: {
|
||||
courseDateBlocks,
|
||||
datesTabLink,
|
||||
userTimezone,
|
||||
},
|
||||
} = useModel('outline', courseId);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { sendTrackEvent, sendTrackingLogEvent } from '@edx/frontend-platform/analytics';
|
||||
import { sendTrackingLogEvent } from '@edx/frontend-platform/analytics';
|
||||
import { getAuthenticatedUser } from '@edx/frontend-platform/auth';
|
||||
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
@@ -36,16 +36,6 @@ function CourseTools({ courseId, intl }) {
|
||||
is_staff: administrator,
|
||||
tool_name: analyticsId,
|
||||
});
|
||||
|
||||
if (analyticsId === 'edx.tool.verified_upgrade') {
|
||||
sendTrackEvent('edx.bi.ecommerce.upsell_links_clicked', {
|
||||
...eventProperties,
|
||||
linkCategory: '(none)',
|
||||
linkName: 'course_home_course_tools',
|
||||
linkType: 'link',
|
||||
pageName: 'course_home',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const renderIcon = (iconClasses) => {
|
||||
|
||||
@@ -9,10 +9,12 @@ import messages from '../messages';
|
||||
import { getProctoringInfoData } from '../../data/api';
|
||||
|
||||
function ProctoringInfoPanel({ courseId, username, intl }) {
|
||||
const [status, setStatus] = useState('');
|
||||
const [link, setLink] = useState('');
|
||||
const [releaseDate, setReleaseDate] = useState(null);
|
||||
const [onboardingPastDue, setOnboardingPastDue] = useState(false);
|
||||
const [showInfoPanel, setShowInfoPanel] = useState(false);
|
||||
const [status, setStatus] = useState('');
|
||||
const [readableStatus, setReadableStatus] = useState('');
|
||||
const [releaseDate, setReleaseDate] = useState(null);
|
||||
|
||||
const readableStatuses = {
|
||||
notStarted: 'notStarted',
|
||||
@@ -77,6 +79,10 @@ function ProctoringInfoPanel({ courseId, username, intl }) {
|
||||
.then(
|
||||
response => {
|
||||
if (response) {
|
||||
if (Object.keys(response).length > 0) {
|
||||
setShowInfoPanel(true);
|
||||
}
|
||||
|
||||
setStatus(response.onboarding_status);
|
||||
setLink(response.onboarding_link);
|
||||
const expirationDate = response.expiration_date;
|
||||
@@ -86,14 +92,54 @@ function ProctoringInfoPanel({ courseId, username, intl }) {
|
||||
setReadableStatus(getReadableStatusClass(response.onboarding_status));
|
||||
}
|
||||
setReleaseDate(new Date(response.onboarding_release_date));
|
||||
setOnboardingPastDue(response.onboarding_past_due);
|
||||
}
|
||||
},
|
||||
);
|
||||
}, []);
|
||||
|
||||
let onboardingExamButton = null;
|
||||
|
||||
if (isNotYetReleased(releaseDate)) {
|
||||
onboardingExamButton = (
|
||||
<Button variant="secondary" block disabled aria-disabled="true">
|
||||
{intl.formatMessage(
|
||||
messages.proctoringOnboardingButtonNotOpen,
|
||||
{
|
||||
releaseDate: intl.formatDate(releaseDate, {
|
||||
day: 'numeric',
|
||||
month: 'short',
|
||||
year: 'numeric',
|
||||
}),
|
||||
},
|
||||
)}
|
||||
</Button>
|
||||
);
|
||||
} else if (onboardingPastDue) {
|
||||
onboardingExamButton = (
|
||||
<Button variant="secondary" block disabled aria-disabled="true">
|
||||
{intl.formatMessage(messages.proctoringOnboardingButtonPastDue)}
|
||||
</Button>
|
||||
);
|
||||
} else if (!isNotYetReleased(releaseDate)) {
|
||||
if (readableStatus === readableStatuses.otherCourseApproved) {
|
||||
onboardingExamButton = (
|
||||
<Button variant="primary" block href={link}>
|
||||
{intl.formatMessage(messages.proctoringOnboardingPracticeButton)}
|
||||
</Button>
|
||||
);
|
||||
} else if (readableStatus !== readableStatuses.otherCourseApproved) {
|
||||
onboardingExamButton = (
|
||||
<Button variant="primary" block href={link}>
|
||||
{intl.formatMessage(messages.proctoringOnboardingButton)}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{ link && (
|
||||
{ showInfoPanel && (
|
||||
<section className={`mb-4 p-3 outline-sidebar-proctoring-panel ${getBorderClass()}`}>
|
||||
<h2 className="h4" id="outline-sidebar-upgrade-header">{intl.formatMessage(messages.proctoringInfoPanel)}</h2>
|
||||
<div>
|
||||
@@ -114,50 +160,17 @@ function ProctoringInfoPanel({ courseId, username, intl }) {
|
||||
<>
|
||||
<p>
|
||||
{isNotYetSubmitted(status) && (
|
||||
<>
|
||||
{intl.formatMessage(messages.proctoringPanelGeneralInfo)}
|
||||
</>
|
||||
intl.formatMessage(messages.proctoringPanelGeneralInfo)
|
||||
)}
|
||||
{!isNotYetSubmitted(status) && (
|
||||
<>
|
||||
{intl.formatMessage(messages.proctoringPanelGeneralInfoSubmitted)}
|
||||
</>
|
||||
intl.formatMessage(messages.proctoringPanelGeneralInfoSubmitted)
|
||||
)}
|
||||
</p>
|
||||
<p>{intl.formatMessage(messages.proctoringPanelGeneralTime)}</p>
|
||||
</>
|
||||
)}
|
||||
{isNotYetSubmitted(status) && (
|
||||
<>
|
||||
{!isNotYetReleased(releaseDate) && (
|
||||
<Button variant="primary" block href={link}>
|
||||
{readableStatus === readableStatuses.otherCourseApproved && (
|
||||
<>
|
||||
{intl.formatMessage(messages.proctoringOnboardingPracticeButton)}
|
||||
</>
|
||||
)}
|
||||
{readableStatus !== readableStatuses.otherCourseApproved && (
|
||||
<>
|
||||
{intl.formatMessage(messages.proctoringOnboardingButton)}
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
)}
|
||||
{isNotYetReleased(releaseDate) && (
|
||||
<Button variant="secondary" block disabled aria-disabled="true">
|
||||
{intl.formatMessage(
|
||||
messages.proctoringOnboardingButtonNotOpen,
|
||||
{
|
||||
releaseDate: intl.formatDate(releaseDate, {
|
||||
day: 'numeric',
|
||||
month: 'short',
|
||||
year: 'numeric',
|
||||
}),
|
||||
},
|
||||
)}
|
||||
</Button>
|
||||
)}
|
||||
</>
|
||||
onboardingExamButton
|
||||
)}
|
||||
<Button variant="outline-primary" block href="https://support.edx.org/hc/en-us/sections/115004169247-Taking-Timed-and-Proctored-Exams">
|
||||
{intl.formatMessage(messages.proctoringReviewRequirementsButton)}
|
||||
|
||||
@@ -12,6 +12,7 @@ import { appendBrowserTimezoneToUrl, executeThunk } from '../../utils';
|
||||
import * as thunks from '../data/thunks';
|
||||
import initializeStore from '../../store';
|
||||
import ProgressTab from './ProgressTab';
|
||||
import LoadedTabPage from '../../tab-page/LoadedTabPage';
|
||||
|
||||
initializeMockApp();
|
||||
jest.mock('@edx/frontend-platform/analytics');
|
||||
@@ -20,9 +21,10 @@ describe('Progress Tab', () => {
|
||||
let axiosMock;
|
||||
|
||||
const courseId = 'course-v1:edX+Test+run';
|
||||
let courseMetadataUrl = `${getConfig().LMS_BASE_URL}/api/course_home/v1/course_metadata/${courseId}`;
|
||||
let courseMetadataUrl = `${getConfig().LMS_BASE_URL}/api/course_home/course_metadata/${courseId}`;
|
||||
courseMetadataUrl = appendBrowserTimezoneToUrl(courseMetadataUrl);
|
||||
const progressUrl = new RegExp(`${getConfig().LMS_BASE_URL}/api/course_home/v1/progress/*`);
|
||||
const progressUrl = new RegExp(`${getConfig().LMS_BASE_URL}/api/course_home/progress/*`);
|
||||
const masqueradeUrl = `${getConfig().LMS_BASE_URL}/courses/${courseId}/masquerade`;
|
||||
|
||||
const store = initializeStore();
|
||||
const defaultMetadata = Factory.build('courseHomeMetadata', { id: courseId });
|
||||
@@ -49,6 +51,7 @@ describe('Progress Tab', () => {
|
||||
// Set defaults for network requests
|
||||
axiosMock.onGet(courseMetadataUrl).reply(200, defaultMetadata);
|
||||
axiosMock.onGet(progressUrl).reply(200, defaultTabData);
|
||||
axiosMock.onGet(masqueradeUrl).reply(200, { success: true });
|
||||
|
||||
logUnhandledRequests(axiosMock);
|
||||
});
|
||||
@@ -1186,6 +1189,64 @@ describe('Progress Tab', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Access expiration masquerade banner', () => {
|
||||
it('renders banner when masquerading as a user', async () => {
|
||||
setMetadata({ is_enrolled: true, original_user_is_staff: true });
|
||||
setTabData({
|
||||
access_expiration: {
|
||||
expiration_date: '2020-01-01T12:00:00Z',
|
||||
masquerading_expired_course: true,
|
||||
},
|
||||
});
|
||||
await executeThunk(thunks.fetchProgressTab(courseId), store.dispatch);
|
||||
await act(async () => render(<LoadedTabPage courseId={courseId} activeTabSlug="progress">...</LoadedTabPage>, { store }));
|
||||
expect(screen.getByTestId('instructor-toolbar')).toBeInTheDocument();
|
||||
expect(screen.getByText('This learner no longer has access to this course. Their access expired on', { exact: false })).toBeInTheDocument();
|
||||
expect(screen.getByText('1/1/2020')).toBeInTheDocument();
|
||||
});
|
||||
it('does not render banner when not masquerading', async () => {
|
||||
setMetadata({ is_enrolled: true, original_user_is_staff: true });
|
||||
setTabData({
|
||||
access_expiration: {
|
||||
expiration_date: '2020-01-01T12:00:00Z',
|
||||
masquerading_expired_course: false,
|
||||
},
|
||||
});
|
||||
await executeThunk(thunks.fetchProgressTab(courseId), store.dispatch);
|
||||
await act(async () => render(<LoadedTabPage courseId={courseId} activeTabSlug="progress">...</LoadedTabPage>, { store }));
|
||||
expect(screen.queryByText('This learner no longer has access to this course. Their access expired on', { exact: false })).not.toBeInTheDocument();
|
||||
expect(screen.queryByText('1/1/2020')).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Course start masquerade banner', () => {
|
||||
it('renders banner when masquerading as a user', async () => {
|
||||
setMetadata({
|
||||
is_enrolled: true,
|
||||
original_user_is_staff: true,
|
||||
is_staff: false,
|
||||
start: '2999-01-01T00:00:00Z',
|
||||
});
|
||||
await executeThunk(thunks.fetchProgressTab(courseId), store.dispatch);
|
||||
await act(async () => render(<LoadedTabPage courseId={courseId} activeTabSlug="progress">...</LoadedTabPage>, { store }));
|
||||
expect(screen.getByTestId('instructor-toolbar')).toBeInTheDocument();
|
||||
expect(screen.getByText('This learner does not yet have access to this course. The course starts on', { exact: false })).toBeInTheDocument();
|
||||
expect(screen.getByText('1/1/2999')).toBeInTheDocument();
|
||||
});
|
||||
it('does not render banner when not masquerading', async () => {
|
||||
setMetadata({
|
||||
is_enrolled: true,
|
||||
original_user_is_staff: true,
|
||||
is_staff: true,
|
||||
start: '2999-01-01T00:00:00Z',
|
||||
});
|
||||
await executeThunk(thunks.fetchProgressTab(courseId), store.dispatch);
|
||||
await act(async () => render(<LoadedTabPage courseId={courseId} activeTabSlug="progress">...</LoadedTabPage>, { store }));
|
||||
expect(screen.queryByText('This learner does not yet have access to this course. The course starts on', { exact: false })).not.toBeInTheDocument();
|
||||
expect(screen.queryByText('1/1/2999')).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Viewing progress page of other students by changing url', () => {
|
||||
it('Changing the url changes the header', async () => {
|
||||
setMetadata({ is_enrolled: true });
|
||||
|
||||
@@ -130,7 +130,7 @@ function CertificateStatus({ intl }) {
|
||||
<FormattedMessage
|
||||
id="progress.certificateStatus.downloadableBody"
|
||||
defaultMessage="
|
||||
Showcase your accomplishment on LinkedIn or your resume today.
|
||||
Showcase your accomplishment on LinkedIn or your resumé today.
|
||||
You can download your certificate now and access it any time from your
|
||||
{dashboardLink} and {profileLink}."
|
||||
values={{ dashboardLink, profileLink }}
|
||||
|
||||
@@ -47,7 +47,7 @@ const messages = defineMessages({
|
||||
},
|
||||
downloadableBody: {
|
||||
id: 'progress.certificateStatus.downloadableBody',
|
||||
defaultMessage: 'Showcase your accomplishment on LinkedIn or your resume today. You can download your certificate now and access it any time from your Dashboard and Profile.',
|
||||
defaultMessage: 'Showcase your accomplishment on LinkedIn or your resumé today. You can download your certificate now and access it any time from your Dashboard and Profile.',
|
||||
},
|
||||
downloadableButton: {
|
||||
id: 'progress.certificateStatus.downloadableButton',
|
||||
|
||||
@@ -51,7 +51,7 @@ function DetailedGradesTable({ intl }) {
|
||||
Header: `${intl.formatMessage(messages.score)}`,
|
||||
accessor: 'score',
|
||||
headerClassName: 'justify-content-end h5 mb-0',
|
||||
cellClassName: 'float-right text-right small',
|
||||
cellClassName: 'align-top text-right small',
|
||||
},
|
||||
]}
|
||||
>
|
||||
|
||||
@@ -52,7 +52,17 @@ function SubsectionTitleCell({ intl, subsection }) {
|
||||
<Collapsible.Visible whenOpen><Icon src={ArrowDropUp} /></Collapsible.Visible>
|
||||
</Collapsible.Trigger>
|
||||
<span className="small d-inline ml-4 pl-1">
|
||||
{gradesFeatureIsFullyLocked || subsection.learnerHasAccess ? '' : <Icon id={`detailedGradesBlockedIcon${subsection.blockKey}`} aria-label={intl.formatMessage(messages.noAcessToSubsection, { displayName })} className="mr-1 mt-1 d-inline-flex" style={{ height: '1rem', width: '1rem' }} src={Blocked} data-testid="blocked-icon" />}
|
||||
{gradesFeatureIsFullyLocked || subsection.learnerHasAccess ? ''
|
||||
: (
|
||||
<Icon
|
||||
id={`detailedGradesBlockedIcon${subsection.blockKey}`}
|
||||
aria-label={intl.formatMessage(messages.noAccessToSubsection, { displayName })}
|
||||
className="mr-1 mt-1 d-inline-flex"
|
||||
style={{ height: '1rem', width: '1rem' }}
|
||||
src={Blocked}
|
||||
data-testid="blocked-icon"
|
||||
/>
|
||||
)}
|
||||
{url ? (
|
||||
<a
|
||||
href={url}
|
||||
@@ -68,7 +78,7 @@ function SubsectionTitleCell({ intl, subsection }) {
|
||||
)}
|
||||
</span>
|
||||
</Row>
|
||||
<Collapsible.Body>
|
||||
<Collapsible.Body className="d-flex w-100">
|
||||
<ProblemScoreDrawer problemScores={problemScores} subsection={subsection} />
|
||||
</Collapsible.Body>
|
||||
</Collapsible.Advanced>
|
||||
|
||||
@@ -18,25 +18,28 @@ function AssignmentTypeCell({
|
||||
gradesFeatureIsFullyLocked,
|
||||
} = useModel('progress', courseId);
|
||||
|
||||
const lockedIcon = locked ? <Icon id={`assignmentTypeBlockedIcon${assignmentType}`} aria-label={intl.formatMessage(messages.noAcessToAssignmentType, { assignmentType })} className="mr-1 mt-1 d-inline-flex" style={{ height: '1rem', width: '1rem' }} src={Blocked} data-testid="blocked-icon" /> : '';
|
||||
const lockedIcon = locked ? <Icon id={`assignmentTypeBlockedIcon${assignmentType}`} aria-label={intl.formatMessage(messages.noAccessToAssignmentType, { assignmentType })} className="mr-1 mt-1 d-inline-flex" style={{ height: '1rem', width: '1rem' }} src={Blocked} data-testid="blocked-icon" /> : '';
|
||||
|
||||
return (
|
||||
<div className="small">
|
||||
<span className="d-inline-flex">{lockedIcon}{assignmentType}</span>
|
||||
{footnoteId && footnoteMarker && (
|
||||
<sup>
|
||||
<a
|
||||
id={`${footnoteId}-ref`}
|
||||
className="muted-link"
|
||||
href={`#${footnoteId}-footnote`}
|
||||
aria-describedby="grade-summary-footnote-label"
|
||||
tabIndex={gradesFeatureIsFullyLocked ? '-1' : '0'}
|
||||
aria-labelledby={`assignmentTypeBlockedIcon${assignmentType}`}
|
||||
>
|
||||
{footnoteMarker}
|
||||
</a>
|
||||
</sup>
|
||||
)}
|
||||
<div className="d-flex small">
|
||||
<div className="d-flex">{lockedIcon}</div>
|
||||
<div>
|
||||
{assignmentType}
|
||||
{footnoteId && footnoteMarker && (
|
||||
<sup>
|
||||
<a
|
||||
id={`${footnoteId}-ref`}
|
||||
className="muted-link"
|
||||
href={`#${footnoteId}-footnote`}
|
||||
aria-describedby="grade-summary-footnote-label"
|
||||
tabIndex={gradesFeatureIsFullyLocked ? '-1' : '0'}
|
||||
aria-labelledby={`assignmentTypeBlockedIcon${assignmentType}`}
|
||||
>
|
||||
{footnoteMarker}
|
||||
</a>
|
||||
</sup>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ function GradeSummaryTable({ intl, setAllOfSomeAssignmentTypeIsLocked }) {
|
||||
Cell: ({ value }) => (
|
||||
<span className={value.locked ? 'greyed-out' : ''}>{value.weight}</span> // eslint-disable-line react/prop-types
|
||||
),
|
||||
cellClassName: 'float-right small',
|
||||
cellClassName: 'text-right small',
|
||||
},
|
||||
{
|
||||
Header: `${intl.formatMessage(messages.grade)}`,
|
||||
@@ -114,7 +114,7 @@ function GradeSummaryTable({ intl, setAllOfSomeAssignmentTypeIsLocked }) {
|
||||
Cell: ({ value }) => (
|
||||
<span className={value.locked ? 'greyed-out' : ''}>{value.grade}</span> // eslint-disable-line react/prop-types
|
||||
),
|
||||
cellClassName: 'float-right small',
|
||||
cellClassName: 'text-right small',
|
||||
},
|
||||
{
|
||||
Header: `${intl.formatMessage(messages.weightedGrade)}`,
|
||||
@@ -124,7 +124,7 @@ function GradeSummaryTable({ intl, setAllOfSomeAssignmentTypeIsLocked }) {
|
||||
Cell: ({ value }) => (
|
||||
<span className={value.locked ? 'greyed-out' : ''}>{value.weightedGrade}</span> // eslint-disable-line react/prop-types
|
||||
),
|
||||
cellClassName: 'float-right font-weight-bold small',
|
||||
cellClassName: 'text-right font-weight-bold small',
|
||||
},
|
||||
]}
|
||||
>
|
||||
|
||||
@@ -139,11 +139,11 @@ const messages = defineMessages({
|
||||
id: 'progress.weightedGradeSummary',
|
||||
defaultMessage: 'Your current weighted grade summary',
|
||||
},
|
||||
noAcessToAssignmentType: {
|
||||
noAccessToAssignmentType: {
|
||||
id: 'progress.noAcessToAssignmentType',
|
||||
defaultMessage: 'You do not have access to assignments of type {assignmentType}',
|
||||
},
|
||||
noAcessToSubsection: {
|
||||
noAccessToSubsection: {
|
||||
id: 'progress.noAcessToSubsection',
|
||||
defaultMessage: 'You do not have access to subsection {displayName}',
|
||||
},
|
||||
|
||||
@@ -57,16 +57,6 @@ const checkUnitToSequenceUnitRedirect = memoize((courseStatus, courseId, sequenc
|
||||
}
|
||||
});
|
||||
|
||||
const checkSpecialExamRedirect = memoize((sequenceStatus, sequence, specialExamsEnabled, proctoredExamsEnabled) => {
|
||||
if (sequenceStatus === 'loaded') {
|
||||
const shouldRedirectTimeLimited = sequence.isTimeLimited && !specialExamsEnabled;
|
||||
const shouldRedirectProctored = sequence.isProctored && !proctoredExamsEnabled;
|
||||
if ((shouldRedirectTimeLimited || shouldRedirectProctored) && sequence.legacyWebUrl !== undefined) {
|
||||
global.location.assign(sequence.legacyWebUrl);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const checkSequenceToSequenceUnitRedirect = memoize((courseId, sequenceStatus, sequence, unitId) => {
|
||||
if (sequenceStatus === 'loaded' && sequence.id && !unitId) {
|
||||
if (sequence.unitIds !== undefined && sequence.unitIds.length > 0) {
|
||||
@@ -121,8 +111,6 @@ class CoursewareContainer extends Component {
|
||||
sequenceId,
|
||||
courseStatus,
|
||||
sequenceStatus,
|
||||
specialExamsEnabledWaffleFlag,
|
||||
proctoredExamsEnabledWaffleFlag,
|
||||
sequence,
|
||||
firstSequenceId,
|
||||
unitViaSequenceId,
|
||||
@@ -175,11 +163,6 @@ class CoursewareContainer extends Component {
|
||||
// by filling in the ID of the parent sequence of :unitId.
|
||||
checkUnitToSequenceUnitRedirect(courseStatus, courseId, sequenceStatus, unitViaSequenceId);
|
||||
|
||||
// Check special exam redirect:
|
||||
// /course/:courseId/:sequenceId(/:unitId) -> :legacyWebUrl
|
||||
// because special exams are currently still served in the legacy LMS frontend.
|
||||
checkSpecialExamRedirect(sequenceStatus, sequence, specialExamsEnabledWaffleFlag, proctoredExamsEnabledWaffleFlag);
|
||||
|
||||
// Check to sequence to sequence-unit redirect:
|
||||
// /course/:courseId/:sequenceId -> /course/:courseId/:sequenceId/:unitId
|
||||
// by filling in the ID the most-recently-active unit in the sequence, OR
|
||||
@@ -324,8 +307,6 @@ CoursewareContainer.propTypes = {
|
||||
checkBlockCompletion: PropTypes.func.isRequired,
|
||||
fetchCourse: PropTypes.func.isRequired,
|
||||
fetchSequence: PropTypes.func.isRequired,
|
||||
specialExamsEnabledWaffleFlag: PropTypes.bool.isRequired,
|
||||
proctoredExamsEnabledWaffleFlag: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
CoursewareContainer.defaultProps = {
|
||||
@@ -429,8 +410,6 @@ const mapStateToProps = (state) => {
|
||||
sequenceId,
|
||||
courseStatus,
|
||||
sequenceStatus,
|
||||
specialExamsEnabledWaffleFlag,
|
||||
proctoredExamsEnabledWaffleFlag,
|
||||
} = state.courseware;
|
||||
|
||||
return {
|
||||
@@ -438,8 +417,6 @@ const mapStateToProps = (state) => {
|
||||
sequenceId,
|
||||
courseStatus,
|
||||
sequenceStatus,
|
||||
specialExamsEnabledWaffleFlag,
|
||||
proctoredExamsEnabledWaffleFlag,
|
||||
course: currentCourseSelector(state),
|
||||
sequence: currentSequenceSelector(state),
|
||||
previousSequence: previousSequenceSelector(state),
|
||||
|
||||
@@ -397,8 +397,6 @@ describe('CoursewareContainer', () => {
|
||||
|
||||
describe('when the current sequence is an exam', () => {
|
||||
const { location } = window;
|
||||
const sequenceBlock = defaultSequenceBlock;
|
||||
const unitBlocks = defaultUnitBlocks;
|
||||
|
||||
beforeEach(() => {
|
||||
delete window.location;
|
||||
@@ -410,20 +408,6 @@ describe('CoursewareContainer', () => {
|
||||
afterEach(() => {
|
||||
window.location = location;
|
||||
});
|
||||
|
||||
it('should redirect to the sequence legacyWebUrl', async () => {
|
||||
const sequenceMetadata = Factory.build(
|
||||
'sequenceMetadata',
|
||||
{ is_time_limited: true }, // position index is 1-based and is converted to 0-based for activeUnitIndex
|
||||
{ courseId, unitBlocks, sequenceBlock },
|
||||
);
|
||||
setUpMockRequests({ sequenceMetadatas: [sequenceMetadata] });
|
||||
|
||||
history.push(`/course/${courseId}/${sequenceBlock.id}/${unitBlocks[2].id}`);
|
||||
await loadContainer();
|
||||
|
||||
expect(global.location.assign).toHaveBeenCalledWith(sequenceBlock.legacy_web_url);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import NotificationTrigger from './NotificationTrigger';
|
||||
|
||||
import { useModel } from '../../generic/model-store';
|
||||
import useWindowSize, { responsiveBreakpoints } from '../../generic/tabs/useWindowSize';
|
||||
import { getLocalStorage, setLocalStorage } from '../../data/localStorage';
|
||||
|
||||
/** [MM-P2P] Experiment */
|
||||
import { initCoursewareMMP2P, MMP2PBlockModal } from '../../experiments/mm-p2p';
|
||||
@@ -60,6 +61,22 @@ function Course({
|
||||
if (notificationTrayVisible) { setNotificationTray(false); } else { setNotificationTray(true); }
|
||||
};
|
||||
|
||||
if (!getLocalStorage('notificationStatus')) {
|
||||
setLocalStorage('notificationStatus', 'active'); // Show red dot on notificationTrigger until seen
|
||||
}
|
||||
|
||||
if (!getLocalStorage('upgradeNotificationCurrentState')) {
|
||||
setLocalStorage('upgradeNotificationCurrentState', 'initialize');
|
||||
}
|
||||
|
||||
const [notificationStatus, setNotificationStatus] = useState(getLocalStorage('notificationStatus'));
|
||||
const [upgradeNotificationCurrentState, setupgradeNotificationCurrentState] = useState(getLocalStorage('upgradeNotificationCurrentState'));
|
||||
|
||||
const onNotificationSeen = () => {
|
||||
setNotificationStatus('inactive');
|
||||
setLocalStorage('notificationStatus', 'inactive');
|
||||
};
|
||||
|
||||
/** [MM-P2P] Experiment */
|
||||
const MMP2P = initCoursewareMMP2P(courseId, sequenceId, unitId);
|
||||
|
||||
@@ -73,6 +90,8 @@ function Course({
|
||||
courseId={courseId}
|
||||
sectionId={section ? section.id : null}
|
||||
sequenceId={sequenceId}
|
||||
isStaff={course ? course.isStaff : null}
|
||||
unitId={unitId}
|
||||
//* * [MM-P2P] Experiment */
|
||||
mmp2p={MMP2P}
|
||||
/>
|
||||
@@ -81,6 +100,9 @@ function Course({
|
||||
<NotificationTrigger
|
||||
toggleNotificationTray={toggleNotificationTray}
|
||||
isNotificationTrayVisible={isNotificationTrayVisible}
|
||||
notificationStatus={notificationStatus}
|
||||
setNotificationStatus={setNotificationStatus}
|
||||
upgradeNotificationCurrentState={upgradeNotificationCurrentState}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
@@ -96,6 +118,11 @@ function Course({
|
||||
toggleNotificationTray={toggleNotificationTray}
|
||||
isNotificationTrayVisible={isNotificationTrayVisible}
|
||||
notificationTrayVisible={notificationTrayVisible}
|
||||
notificationStatus={notificationStatus}
|
||||
setNotificationStatus={setNotificationStatus}
|
||||
onNotificationSeen={onNotificationSeen}
|
||||
upgradeNotificationCurrentState={upgradeNotificationCurrentState}
|
||||
setupgradeNotificationCurrentState={setupgradeNotificationCurrentState}
|
||||
//* * [MM-P2P] Experiment */
|
||||
mmp2p={MMP2P}
|
||||
/>
|
||||
|
||||
@@ -91,6 +91,31 @@ describe('Course', () => {
|
||||
expect(notificationTrigger).not.toHaveClass('trigger-active');
|
||||
});
|
||||
|
||||
it('renders course breadcrumbs as expected', async () => {
|
||||
const courseMetadata = Factory.build('courseMetadata');
|
||||
const unitBlocks = Array.from({ length: 3 }).map(() => Factory.build(
|
||||
'block',
|
||||
{ type: 'vertical' },
|
||||
{ courseId: courseMetadata.id },
|
||||
));
|
||||
const testStore = await initializeTestStore({ courseMetadata, unitBlocks }, false);
|
||||
const { courseware, models } = testStore.getState();
|
||||
const { courseId, sequenceId } = courseware;
|
||||
const testData = {
|
||||
...mockData,
|
||||
courseId,
|
||||
sequenceId,
|
||||
unitId: Object.values(models.units)[1].id, // Corner cases are already covered in `Sequence` tests.
|
||||
};
|
||||
render(<Course {...testData} />, { store: testStore });
|
||||
|
||||
loadUnit();
|
||||
await waitFor(() => expect(screen.queryByText('Loading learning sequence...')).not.toBeInTheDocument());
|
||||
// expect the section and sequence "titles" to be loaded in as breadcrumb labels.
|
||||
expect(screen.getByText('cdabcdabcdabcdabcdabcdabcdabcd13')).toBeInTheDocument();
|
||||
expect(screen.getByText('cdabcdabcdabcdabcdabcdabcdabcd12')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('passes handlers to the sequence', async () => {
|
||||
const nextSequenceHandler = jest.fn();
|
||||
const previousSequenceHandler = jest.fn();
|
||||
|
||||
@@ -1,95 +1,150 @@
|
||||
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 { useSelector } from 'react-redux';
|
||||
import { useModel } from '../../generic/model-store';
|
||||
|
||||
import { SelectMenu } from '@edx/paragon';
|
||||
import { useModel, useModels } from '../../generic/model-store';
|
||||
/** [MM-P2P] Experiment */
|
||||
import { MMP2PFlyoverTrigger } from '../../experiments/mm-p2p';
|
||||
import JumpNavMenuItem from './JumpNavMenuItem';
|
||||
|
||||
function CourseBreadcrumb({
|
||||
url, children, withSeparator, ...attrs
|
||||
content, withSeparator, courseId, unitId, isStaff,
|
||||
}) {
|
||||
const defaultContent = content.filter(destination => destination.default)[0] || { id: courseId, label: '' };
|
||||
|
||||
return (
|
||||
<>
|
||||
{withSeparator && (
|
||||
<li className="mx-2 text-primary-500" role="presentation" aria-hidden>/</li>
|
||||
<li className="mx-2 text-primary-500 text-truncate text-nowrap" role="presentation" aria-hidden>/</li>
|
||||
)}
|
||||
<li {...attrs}>
|
||||
<a className="text-primary-500" href={url}>{children}</a>
|
||||
|
||||
<li style={{
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
whiteSpace: 'nowrap',
|
||||
}}
|
||||
>
|
||||
{content.length < 2 || !isStaff
|
||||
? (
|
||||
<a className="text-primary-500" href={`/course/${courseId}/${defaultContent.id}`}>
|
||||
{defaultContent.label}
|
||||
</a>
|
||||
)
|
||||
: (
|
||||
<SelectMenu isLink defaultMessage={defaultContent.label}>
|
||||
{content.map(item => (
|
||||
<JumpNavMenuItem
|
||||
isDefault={item.default}
|
||||
sequences={item.sequences}
|
||||
courseId={courseId}
|
||||
title={item.label}
|
||||
currentUnit={unitId}
|
||||
/>
|
||||
))}
|
||||
</SelectMenu>
|
||||
)}
|
||||
|
||||
</li>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
CourseBreadcrumb.propTypes = {
|
||||
url: PropTypes.string.isRequired,
|
||||
children: PropTypes.node.isRequired,
|
||||
content: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
default: PropTypes.bool,
|
||||
id: PropTypes.string,
|
||||
label: PropTypes.string,
|
||||
}),
|
||||
).isRequired,
|
||||
unitId: PropTypes.string,
|
||||
withSeparator: PropTypes.bool,
|
||||
courseId: PropTypes.string,
|
||||
isStaff: PropTypes.bool,
|
||||
};
|
||||
|
||||
CourseBreadcrumb.defaultProps = {
|
||||
withSeparator: false,
|
||||
unitId: null,
|
||||
courseId: null,
|
||||
isStaff: null,
|
||||
};
|
||||
|
||||
export default function CourseBreadcrumbs({
|
||||
courseId,
|
||||
sectionId,
|
||||
sequenceId,
|
||||
unitId,
|
||||
isStaff,
|
||||
/** [MM-P2P] Experiment */
|
||||
mmp2p,
|
||||
}) {
|
||||
const course = useModel('coursewareMeta', courseId);
|
||||
const sequence = useModel('sequences', sequenceId);
|
||||
const section = useModel('sections', sectionId);
|
||||
const courseStatus = useSelector(state => state.courseware.courseStatus);
|
||||
const sequenceStatus = useSelector(state => state.courseware.sequenceStatus);
|
||||
|
||||
const allSequencesInSections = Object.fromEntries(useModels('sections', course.sectionIds).map(section => [section.id, {
|
||||
default: section.id === sectionId,
|
||||
title: section.title,
|
||||
sequences: useModels('sequences', section.sequenceIds),
|
||||
}]));
|
||||
|
||||
const links = useMemo(() => {
|
||||
const chapters = [];
|
||||
const sequentials = [];
|
||||
if (courseStatus === 'loaded' && sequenceStatus === 'loaded') {
|
||||
return [section, sequence].filter(node => !!node).map((node) => ({
|
||||
id: node.id,
|
||||
label: node.title,
|
||||
url: `${getConfig().LMS_BASE_URL}/courses/${course.id}/course/#${node.id}`,
|
||||
}));
|
||||
Object.entries(allSequencesInSections).forEach(([id, section]) => {
|
||||
chapters.push({
|
||||
id,
|
||||
label: section.title,
|
||||
default: section.default,
|
||||
sequences: section.sequences,
|
||||
});
|
||||
if (section.default) {
|
||||
section.sequences.forEach(sequence => {
|
||||
sequentials.push({
|
||||
id: sequence.id,
|
||||
label: sequence.title,
|
||||
default: sequence.id === sequenceId,
|
||||
sequences: [sequence],
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
return [];
|
||||
}, [courseStatus, sequenceStatus]);
|
||||
return [chapters, sequentials];
|
||||
}, [courseStatus, sequenceStatus, allSequencesInSections]);
|
||||
|
||||
return (
|
||||
<nav aria-label="breadcrumb" className="my-4 d-inline-block col-sm-10">
|
||||
<ol className="list-unstyled d-flex m-0">
|
||||
<CourseBreadcrumb
|
||||
url={`${getConfig().LMS_BASE_URL}/courses/${course.id}/course/`}
|
||||
className="flex-shrink-0"
|
||||
>
|
||||
<FontAwesomeIcon icon={faHome} className="mr-2" />
|
||||
<FormattedMessage
|
||||
id="learn.breadcrumb.navigation.course.home"
|
||||
description="The course home link in breadcrumbs nav"
|
||||
defaultMessage="Course"
|
||||
/>
|
||||
</CourseBreadcrumb>
|
||||
{links.map(({ id, url, label }) => (
|
||||
<CourseBreadcrumb
|
||||
key={id}
|
||||
url={url}
|
||||
withSeparator
|
||||
style={{
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
whiteSpace: 'nowrap',
|
||||
}}
|
||||
<ol className="list-unstyled d-flex flex-nowrap align-items-center m-0">
|
||||
<li className="list-unstyled d-flex m-0">
|
||||
<a
|
||||
href={`/course/${courseId}/home`}
|
||||
className="flex-shrink-0 text-primary"
|
||||
>
|
||||
{label}
|
||||
</CourseBreadcrumb>
|
||||
<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(content => (
|
||||
<CourseBreadcrumb
|
||||
courseId={courseId}
|
||||
sequenceId={sequenceId}
|
||||
content={content}
|
||||
unitId={unitId}
|
||||
withSeparator
|
||||
isStaff={isStaff}
|
||||
/>
|
||||
))}
|
||||
|
||||
{/** [MM-P2P] Experiment */}
|
||||
{mmp2p.state.isEnabled && (
|
||||
{mmp2p.state && mmp2p.state.isEnabled && (
|
||||
<MMP2PFlyoverTrigger options={mmp2p} />
|
||||
)}
|
||||
</ol>
|
||||
@@ -101,6 +156,8 @@ CourseBreadcrumbs.propTypes = {
|
||||
courseId: PropTypes.string.isRequired,
|
||||
sectionId: PropTypes.string,
|
||||
sequenceId: PropTypes.string,
|
||||
unitId: PropTypes.string,
|
||||
isStaff: PropTypes.bool,
|
||||
/** [MM-P2P] Experiment */
|
||||
mmp2p: PropTypes.shape({
|
||||
state: PropTypes.shape({
|
||||
@@ -112,7 +169,8 @@ CourseBreadcrumbs.propTypes = {
|
||||
CourseBreadcrumbs.defaultProps = {
|
||||
sectionId: null,
|
||||
sequenceId: null,
|
||||
|
||||
unitId: null,
|
||||
isStaff: null,
|
||||
/** [MM-P2P] Experiment */
|
||||
mmp2p: {},
|
||||
};
|
||||
|
||||
120
src/courseware/course/CourseBreadcrumbs.test.jsx
Normal file
120
src/courseware/course/CourseBreadcrumbs.test.jsx
Normal file
@@ -0,0 +1,120 @@
|
||||
import React from 'react';
|
||||
import { screen, render } from '@testing-library/react';
|
||||
import { getAuthenticatedUser } from '@edx/frontend-platform/auth';
|
||||
import { useModel, useModels } from '../../generic/model-store';
|
||||
import CourseBreadcrumbs from './CourseBreadcrumbs';
|
||||
|
||||
jest.mock('@edx/frontend-platform');
|
||||
jest.mock('@edx/frontend-platform/analytics');
|
||||
|
||||
// Remove When Fully rolled out>>>
|
||||
jest.mock('../../generic/model-store');
|
||||
jest.mock('@edx/frontend-platform/auth');
|
||||
getAuthenticatedUser.mockImplementation(() => ({ administrator: true }));
|
||||
// ^^^^Remove When Fully rolled out
|
||||
|
||||
jest.mock('react-redux', () => ({
|
||||
connect: (mapStateToProps, mapDispatchToProps) => (ReactComponent) => ({
|
||||
mapStateToProps,
|
||||
mapDispatchToProps,
|
||||
ReactComponent,
|
||||
}),
|
||||
Provider: ({ children }) => children,
|
||||
useSelector: () => 'loaded',
|
||||
}));
|
||||
|
||||
useModels.mockImplementation((name) => {
|
||||
if (name === 'sections') {
|
||||
return [
|
||||
{
|
||||
courseId: 'course-v1:edX+DemoX+Demo_Course',
|
||||
id: 'block-v1:edX+DemoX+Demo_Course+type@chapter+block@d8a6192ade314473a78242dfeedfbf5b',
|
||||
sequenceIds: ['block-v1:edX+DemoX+Demo_Course+type@sequential+block@edx_introduction'],
|
||||
title: 'Introduction',
|
||||
},
|
||||
{
|
||||
courseId: 'course-v1:edX+DemoX+Demo_Course',
|
||||
id: 'block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations',
|
||||
sequenceIds: ['block-v1:edX+DemoX+Demo_Course+type@sequential+block@19a30717eff543078a5d94ae9d6c18a5',
|
||||
'block-v1:edX+DemoX+Demo_Course+type@sequential+block@basic_questions'],
|
||||
title: 'Example Week 1: Getting Started',
|
||||
},
|
||||
];
|
||||
}
|
||||
return [
|
||||
{
|
||||
id: 'block-v1:edX+DemoX+Demo_Course+type@sequential+block@19a30717eff543078a5d94ae9d6c18a5',
|
||||
sectionId: 'block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations',
|
||||
title: 'Lesson 1 - Getting Started',
|
||||
unitIds: [
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@867dddb6f55d410caaa9c1eb9c6743ec',
|
||||
'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@256f17a44983429fb1a60802203ee4e0',
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@e3601c0abee6427d8c17e6d6f8fdddd1',
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@134df56c516a4a0dbb24dd5facef746e',
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'block-v1:edX+DemoX+Demo_Course+type@sequential+block@basic_questions',
|
||||
sectionId: 'block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations',
|
||||
title: 'Homework - Question Styles',
|
||||
unitIds: [
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@2152d4a4aadc4cb0af5256394a3d1fc7',
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@47dbd5f836544e61877a483c0b75606c',
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@54bb9b142c6c4c22afc62bcb628f0e68',
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_0c92347a5c00',
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_1fef54c2b23b',
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@2889db1677a549abb15eb4d886f95d1c',
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@e8a5cc2aed424838853defab7be45e42',
|
||||
],
|
||||
},
|
||||
];
|
||||
});
|
||||
useModel.mockImplementation(() => ({
|
||||
sectionIds: ['block-v1:edX+DemoX+Demo_Course+type@chapter+block@d8a6192ade314473a78242dfeedfbf5b',
|
||||
'block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations'],
|
||||
}));
|
||||
|
||||
describe('CourseBreadcrumbs', () => {
|
||||
jest.spyOn(React, 'useMemo').mockImplementation(() => [
|
||||
[
|
||||
{
|
||||
default: false,
|
||||
id: 'block-v1:edX+DemoX+Demo_Course+type@chapter+block@d8a6192ade314473a78242dfeedfbf5b',
|
||||
label: 'Introduction',
|
||||
url: 'http://localhost:2000/course/course-v1:edX+DemoX+Demo_Course/block-v1:edX+DemoX+Demo_Course+type@sequential+block@edx_introduction',
|
||||
},
|
||||
{
|
||||
default: true,
|
||||
id: 'block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations',
|
||||
label: 'Example Week 1: Getting Started',
|
||||
url: 'http://localhost:2000/course/course-v1:edX+DemoX+Demo_Course/block-v1:edX+DemoX+Demo_Course+type@sequential+block@19a30717eff543078a5d94ae9d6c18a5',
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
id: 'block-v1:edX+DemoX+Demo_Course+type@sequential+block@simulations', label: "Lesson 2 - Let's Get Interactive!", default: true, url: 'http://localhost:2000/course/course-v1:edX+DemoX+D…e@vertical+block@d0d804e8863c4a95a659c04d8a2b2bc0',
|
||||
},
|
||||
{
|
||||
id: 'block-v1:edX+DemoX+Demo_Course+type@sequential+block@175e76c4951144a29d46211361266e0e', label: 'Homework - Essays', default: false, url: 'http://localhost:2000/course/course-v1:edX+DemoX+D…e@vertical+block@fb79dcbad35b466a8c6364f8ffee9050',
|
||||
},
|
||||
],
|
||||
]);
|
||||
render(
|
||||
<CourseBreadcrumbs
|
||||
courseId="course-v1:edX+DemoX+Demo_Course"
|
||||
sectionId="block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations"
|
||||
sequenceId="block-v1:edX+DemoX+Demo_Course+type@sequential+block@basic_questions"
|
||||
isStaff
|
||||
/>,
|
||||
);
|
||||
it('renders course breadcrumbs as expected', async () => {
|
||||
expect(screen.queryAllByRole('link')).toHaveLength(1);
|
||||
const courseHomeButtonDestination = screen.getAllByRole('link')[0].href;
|
||||
expect(courseHomeButtonDestination).toBe('http://localhost/course/course-v1:edX+DemoX+Demo_Course/home');
|
||||
expect(screen.getByRole('navigation', { name: 'breadcrumb' })).toBeInTheDocument();
|
||||
expect(screen.queryAllByRole('button')).toHaveLength(2);
|
||||
});
|
||||
});
|
||||
80
src/courseware/course/JumpNavMenuItem.jsx
Normal file
80
src/courseware/course/JumpNavMenuItem.jsx
Normal file
@@ -0,0 +1,80 @@
|
||||
/* eslint-disable consistent-return */
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { history } from '@edx/frontend-platform';
|
||||
import { MenuItem } from '@edx/paragon';
|
||||
|
||||
import {
|
||||
sendTrackingLogEvent,
|
||||
sendTrackEvent,
|
||||
} from '@edx/frontend-platform/analytics';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { checkBlockCompletion } from '../data';
|
||||
|
||||
export default function JumpNavMenuItem({
|
||||
title,
|
||||
courseId,
|
||||
currentUnit,
|
||||
sequences,
|
||||
isDefault,
|
||||
|
||||
}) {
|
||||
const dispatch = useDispatch();
|
||||
function logEvent(targetUrl) {
|
||||
const eventName = 'edx.ui.lms.jump_nav.selected';
|
||||
const payload = {
|
||||
target_name: title,
|
||||
id: targetUrl,
|
||||
current_id: courseId,
|
||||
widget_placement: 'breadcrumb',
|
||||
};
|
||||
sendTrackEvent(eventName, payload);
|
||||
sendTrackingLogEvent(eventName, payload);
|
||||
}
|
||||
|
||||
function lazyloadUrl() {
|
||||
if (isDefault) {
|
||||
return `/course/${courseId}/${currentUnit}`;
|
||||
}
|
||||
const destinationString = sequences.forEach(sequence => sequence.unitIds.forEach(unitId => {
|
||||
const complete = dispatch(checkBlockCompletion(
|
||||
courseId,
|
||||
sequence.id, unitId,
|
||||
))
|
||||
.then(value => value);
|
||||
if (!complete) { return `/course/${courseId}/${unitId}`; }
|
||||
}));
|
||||
return destinationString || `/course/${courseId}/${sequences[0].unitIds[0]}`;
|
||||
}
|
||||
function handleClick() {
|
||||
const url = lazyloadUrl();
|
||||
logEvent(url);
|
||||
history.push(url);
|
||||
}
|
||||
|
||||
return (
|
||||
<MenuItem
|
||||
defaultSelected={isDefault}
|
||||
onClick={() => handleClick()}
|
||||
>
|
||||
{title}
|
||||
</MenuItem>
|
||||
);
|
||||
}
|
||||
|
||||
const sequenceShape = PropTypes.shape({
|
||||
id: PropTypes.string.isRequired,
|
||||
unitIds: PropTypes.arrayOf(PropTypes.string).isRequired,
|
||||
sectionId: PropTypes.string.isRequired,
|
||||
isTimeLimited: PropTypes.bool,
|
||||
isProctored: PropTypes.bool,
|
||||
legacyWebUrl: PropTypes.string,
|
||||
});
|
||||
|
||||
JumpNavMenuItem.propTypes = {
|
||||
title: PropTypes.string.isRequired,
|
||||
sequences: PropTypes.arrayOf(sequenceShape).isRequired,
|
||||
isDefault: PropTypes.bool.isRequired,
|
||||
courseId: PropTypes.string.isRequired,
|
||||
currentUnit: PropTypes.string.isRequired,
|
||||
};
|
||||
69
src/courseware/course/JumpNavMenuItem.test.jsx
Normal file
69
src/courseware/course/JumpNavMenuItem.test.jsx
Normal file
@@ -0,0 +1,69 @@
|
||||
import React from 'react';
|
||||
import { screen, render } from '@testing-library/react';
|
||||
import JumpNavMenuItem from './JumpNavMenuItem';
|
||||
import { fireEvent } from '../../setupTest';
|
||||
|
||||
jest.mock('@edx/frontend-platform');
|
||||
jest.mock('@edx/frontend-platform/analytics');
|
||||
|
||||
const mockCheckBlock = jest.fn(() => Promise.resolve(true)); // check all units
|
||||
|
||||
jest.mock('react-redux', () => ({
|
||||
useDispatch: () => mockCheckBlock,
|
||||
}));
|
||||
|
||||
const mockData = {
|
||||
sectionId: 'block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations',
|
||||
sequenceId: 'block-v1:edX+DemoX+Demo_Course+type@sequential+block@basic_questions',
|
||||
|
||||
title: 'Demo Menu Item',
|
||||
courseId: 'course-v1:edX+DemoX+Demo_Course',
|
||||
currentUnit: 'block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations',
|
||||
sequences: [
|
||||
{
|
||||
id: 'block-v1:edX+DemoX+Demo_Course+type@sequential+block@19a30717eff543078a5d94ae9d6c18a5',
|
||||
blockType: 'sequential',
|
||||
unitIds: [
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@867dddb6f55d410caaa9c1eb9c6743ec',
|
||||
'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@256f17a44983429fb1a60802203ee4e0',
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@e3601c0abee6427d8c17e6d6f8fdddd1',
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@134df56c516a4a0dbb24dd5facef746e',
|
||||
],
|
||||
legacyWebUrl: 'http://localhost:18000/courses/course-v1:edX+DemoX+Demo_Course/jump_to/block-v1:edX+DemoX+Demo_Course+type@sequential+block@19a30717eff543078a5d94ae9d6c18a5?experience=legacy',
|
||||
sectionId: 'block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations',
|
||||
},
|
||||
{
|
||||
id: 'block-v1:edX+DemoX+Demo_Course+type@sequential+block@basic_questions',
|
||||
title: 'Homework - Question Styles',
|
||||
legacyWebUrl: 'http://localhost:18000/courses/course-v1:edX+DemoX+Demo_Course/jump_to/block-v1:edX+DemoX+Demo_Course+type@sequential+block@basic_questions?experience=legacy',
|
||||
unitIds: [
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@2152d4a4aadc4cb0af5256394a3d1fc7',
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@47dbd5f836544e61877a483c0b75606c',
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@54bb9b142c6c4c22afc62bcb628f0e68',
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_0c92347a5c00',
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_1fef54c2b23b',
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@2889db1677a549abb15eb4d886f95d1c',
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@e8a5cc2aed424838853defab7be45e42',
|
||||
],
|
||||
sectionId: 'block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations',
|
||||
},
|
||||
],
|
||||
isDefault: false,
|
||||
};
|
||||
describe('JumpNavMenuItem', () => {
|
||||
render(
|
||||
<JumpNavMenuItem
|
||||
{...mockData}
|
||||
/>,
|
||||
);
|
||||
it('renders menu Item as expected with button and Text and handles clicks', () => {
|
||||
expect(screen.queryAllByRole('button')).toHaveLength(1);
|
||||
expect(screen.getByText('Demo Menu Item'));
|
||||
const navButton = screen.queryAllByRole('button')[0];
|
||||
fireEvent.click(navButton);
|
||||
expect(mockCheckBlock).toBeCalledTimes(14); // number of units to check on load.
|
||||
});
|
||||
});
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
@@ -12,7 +12,7 @@ import useWindowSize, { responsiveBreakpoints } from '../../generic/tabs/useWind
|
||||
import UpgradeNotification from '../../generic/upgrade-notification/UpgradeNotification';
|
||||
|
||||
function NotificationTray({
|
||||
intl, toggleNotificationTray,
|
||||
intl, toggleNotificationTray, onNotificationSeen, upgradeNotificationCurrentState, setupgradeNotificationCurrentState,
|
||||
}) {
|
||||
const {
|
||||
courseId,
|
||||
@@ -32,6 +32,9 @@ function NotificationTray({
|
||||
|
||||
const shouldDisplayFullScreen = useWindowSize().width < responsiveBreakpoints.large.minWidth;
|
||||
|
||||
// After three seconds, update notificationSeen (to hide red dot)
|
||||
useEffect(() => { setTimeout(onNotificationSeen, 3000); }, []);
|
||||
|
||||
return (
|
||||
<section className={classNames('notification-tray-container ml-0 ml-lg-4', { 'no-notification': !verifiedMode && !shouldDisplayFullScreen })} aria-label={intl.formatMessage(messages.notificationTray)}>
|
||||
{shouldDisplayFullScreen ? (
|
||||
@@ -64,6 +67,8 @@ function NotificationTray({
|
||||
timeOffsetMillis={timeOffsetMillis}
|
||||
courseId={courseId}
|
||||
org={org}
|
||||
upgradeNotificationCurrentState={upgradeNotificationCurrentState}
|
||||
setupgradeNotificationCurrentState={setupgradeNotificationCurrentState}
|
||||
/>
|
||||
) : <p className="notification-tray-content">{intl.formatMessage(messages.noNotificationsMessage)}</p>}
|
||||
</div>
|
||||
@@ -74,10 +79,14 @@ function NotificationTray({
|
||||
NotificationTray.propTypes = {
|
||||
intl: intlShape.isRequired,
|
||||
toggleNotificationTray: PropTypes.func,
|
||||
onNotificationSeen: PropTypes.func,
|
||||
upgradeNotificationCurrentState: PropTypes.string.isRequired,
|
||||
setupgradeNotificationCurrentState: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
NotificationTray.defaultProps = {
|
||||
toggleNotificationTray: null,
|
||||
onNotificationSeen: null,
|
||||
};
|
||||
|
||||
export default injectIntl(NotificationTray);
|
||||
|
||||
@@ -1,12 +1,31 @@
|
||||
import React from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
|
||||
import { getLocalStorage, setLocalStorage } from '../../data/localStorage';
|
||||
|
||||
import NotificationIcon from './NotificationIcon';
|
||||
import messages from './messages';
|
||||
|
||||
function NotificationTrigger({ intl, toggleNotificationTray, isNotificationTrayVisible }) {
|
||||
function NotificationTrigger({
|
||||
intl, toggleNotificationTray, isNotificationTrayVisible, notificationStatus, setNotificationStatus,
|
||||
upgradeNotificationCurrentState,
|
||||
}) {
|
||||
/* Re-show a red dot beside the notification trigger for each of the 7 UpgradeNotification stages
|
||||
The upgradeNotificationCurrentState prop will be available after UpgradeNotification mounts. Once available,
|
||||
compare with the last state they've seen, and if it's different then set dot back to red */
|
||||
function UpdateUpgradeNotificationLastSeen() {
|
||||
if (upgradeNotificationCurrentState) {
|
||||
if (getLocalStorage('upgradeNotificationLastSeen') !== upgradeNotificationCurrentState) {
|
||||
setNotificationStatus('active');
|
||||
setLocalStorage('notificationStatus', 'active');
|
||||
setLocalStorage('upgradeNotificationLastSeen', upgradeNotificationCurrentState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => { UpdateUpgradeNotificationLastSeen(); });
|
||||
|
||||
return (
|
||||
<button
|
||||
className={classNames('notification-trigger-btn', { 'trigger-active': isNotificationTrayVisible() })}
|
||||
@@ -14,8 +33,7 @@ function NotificationTrigger({ intl, toggleNotificationTray, isNotificationTrayV
|
||||
onClick={() => { toggleNotificationTray(); }}
|
||||
aria-label={intl.formatMessage(messages.openNotificationTrigger)}
|
||||
>
|
||||
{/* REV-2297 TODO: add logic for status "active" if red dot should display */}
|
||||
<NotificationIcon status="inactive" notificationColor="bg-danger-500" />
|
||||
<NotificationIcon status={notificationStatus} notificationColor="bg-danger-500" />
|
||||
</button>
|
||||
);
|
||||
}
|
||||
@@ -23,7 +41,10 @@ function NotificationTrigger({ intl, toggleNotificationTray, isNotificationTrayV
|
||||
NotificationTrigger.propTypes = {
|
||||
intl: intlShape.isRequired,
|
||||
toggleNotificationTray: PropTypes.func.isRequired,
|
||||
notificationStatus: PropTypes.string.isRequired,
|
||||
setNotificationStatus: PropTypes.func.isRequired,
|
||||
isNotificationTrayVisible: PropTypes.func.isRequired,
|
||||
upgradeNotificationCurrentState: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default injectIntl(NotificationTrigger);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.notification-trigger-btn {
|
||||
border: 1px solid $light-400;
|
||||
background: none;
|
||||
margin-top: 0.625rem;
|
||||
margin-top: 1rem;
|
||||
|
||||
position: absolute;
|
||||
right: 0;
|
||||
|
||||
@@ -4,27 +4,51 @@ import {
|
||||
render, initializeTestStore, screen, fireEvent,
|
||||
} from '../../setupTest';
|
||||
import NotificationTrigger from './NotificationTrigger';
|
||||
import { getLocalStorage } from '../../data/localStorage';
|
||||
|
||||
describe('Notification Trigger', () => {
|
||||
let mockData;
|
||||
// let mockDataSameState;
|
||||
// let mockDataDifferentState;
|
||||
const courseMetadata = Factory.build('courseMetadata');
|
||||
|
||||
beforeAll(async () => {
|
||||
beforeEach(async () => {
|
||||
await initializeTestStore({ courseMetadata, excludeFetchCourse: true, excludeFetchSequence: true });
|
||||
mockData = {
|
||||
toggleNotificationTray: () => {},
|
||||
isNotificationTrayVisible: () => {},
|
||||
notificationStatus: 'active',
|
||||
setNotificationStatus: () => {},
|
||||
upgradeNotificationCurrentState: 'FPDdaysLeft',
|
||||
};
|
||||
});
|
||||
|
||||
it('renders notification trigger with icon', async () => {
|
||||
it('renders notification trigger icon with red dot when notificationStatus is active', async () => {
|
||||
const { container } = render(<NotificationTrigger {...mockData} />);
|
||||
expect(container).toBeInTheDocument();
|
||||
const buttonIcon = container.querySelectorAll('svg');
|
||||
expect(buttonIcon).toHaveLength(1);
|
||||
expect(screen.getByTestId('notification-dot')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// REV-2297 TODO: update below test once the status=active or inactive is implemented
|
||||
// expect(screen.getByTestId('notification-dot')).toBeInTheDocument();
|
||||
it('renders notification trigger icon WITHOUT red dot 3 seconds later', async () => {
|
||||
const { container } = render(<NotificationTrigger {...mockData} />);
|
||||
expect(container).toBeInTheDocument();
|
||||
jest.useFakeTimers();
|
||||
setTimeout(() => {
|
||||
expect(screen.queryByRole('notification-dot')).not.toBeInTheDocument();
|
||||
}, 3000);
|
||||
jest.runAllTimers();
|
||||
});
|
||||
|
||||
it('renders notification trigger icon WITHOUT red dot within the same phase', async () => {
|
||||
const { container } = render(
|
||||
<NotificationTrigger {...mockData} upgradeNotificationCurrentState="sameState" upgradeNotificationLastSeen="sameState" />,
|
||||
);
|
||||
expect(container).toBeInTheDocument();
|
||||
const buttonIcon = container.querySelectorAll('svg');
|
||||
expect(buttonIcon).toHaveLength(1);
|
||||
expect(screen.queryByRole('notification-dot')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('handles onClick event toggling the notification tray', async () => {
|
||||
@@ -40,4 +64,16 @@ describe('Notification Trigger', () => {
|
||||
fireEvent.click(notificationTrigger);
|
||||
expect(toggleNotificationTray).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
// rendering NotificationTrigger has the effect of calling UpdateUpgradeNotificationLastSeen()
|
||||
// Verify that local storage was updated accordingly
|
||||
it('we make the right updates when rendering a new phase (before -> after)', async () => {
|
||||
const { container } = render(
|
||||
<NotificationTrigger {...mockData} upgradeNotificationLastSeen="before" upgradeNotificationCurrentState="after" />,
|
||||
);
|
||||
expect(container).toBeInTheDocument();
|
||||
|
||||
expect(getLocalStorage('notificationStatus')).toBe('active');
|
||||
expect(getLocalStorage('upgradeNotificationLastSeen')).toBe('after');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
|
||||
@@ -11,6 +11,7 @@ import CourseInProgress from './CourseInProgress';
|
||||
import CourseNonPassing from './CourseNonPassing';
|
||||
import { COURSE_EXIT_MODES, getCourseExitMode } from './utils';
|
||||
import messages from './messages';
|
||||
import { unsubscribeFromGoalReminders } from './data/thunks';
|
||||
|
||||
import { useModel } from '../../../generic/model-store';
|
||||
|
||||
@@ -18,10 +19,13 @@ function CourseExit({ intl }) {
|
||||
const { courseId } = useSelector(state => state.courseware);
|
||||
const {
|
||||
certificateData,
|
||||
courseExitPageIsActive,
|
||||
courseGoals,
|
||||
enrollmentMode,
|
||||
hasScheduledContent,
|
||||
isEnrolled,
|
||||
isMasquerading,
|
||||
userHasPassingGrade,
|
||||
courseExitPageIsActive,
|
||||
} = useModel('coursewareMeta', courseId);
|
||||
|
||||
const mode = getCourseExitMode(
|
||||
@@ -32,6 +36,15 @@ function CourseExit({ intl }) {
|
||||
courseExitPageIsActive,
|
||||
);
|
||||
|
||||
// Audit users cannot fully complete a course, so we will
|
||||
// unsubscribe them from goal reminders once they reach the course exit page
|
||||
// to avoid spamming them with goal reminder emails
|
||||
if (courseGoals && enrollmentMode === 'audit' && !isMasquerading) {
|
||||
useEffect(() => {
|
||||
unsubscribeFromGoalReminders(courseId);
|
||||
}, []);
|
||||
}
|
||||
|
||||
let body = null;
|
||||
if (mode === COURSE_EXIT_MODES.nonPassing) {
|
||||
body = (<CourseNonPassing />);
|
||||
|
||||
@@ -3,6 +3,7 @@ import MockAdapter from 'axios-mock-adapter';
|
||||
import { Factory } from 'rosie';
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
|
||||
import { waitFor } from '@testing-library/react';
|
||||
|
||||
import { fetchCourse } from '../../data';
|
||||
import { buildSimpleCourseBlocks } from '../../../shared/data/__factories__/courseBlocks.factory';
|
||||
@@ -377,4 +378,25 @@ describe('Course Exit Pages', () => {
|
||||
expect(screen.getByRole('link', { name: 'View course schedule' })).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it('unsubscribes the user when loading the course exit page', async () => {
|
||||
setMetadata({
|
||||
enrollment: {
|
||||
mode: 'audit',
|
||||
courseGoals: {
|
||||
goal_options: [],
|
||||
selected_goal: {
|
||||
days_per_week: 1,
|
||||
subscribed_to_reminders: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
await fetchAndRender(<CourseExit />);
|
||||
const url = `${getConfig().LMS_BASE_URL}/api/course_home/save_course_goal`;
|
||||
await waitFor(() => {
|
||||
expect(axiosMock.history.post[0].url).toMatch(url);
|
||||
expect(axiosMock.history.post[0].data).toMatch(`{"course_id":"${defaultMetadata.id}","subscribed_to_reminders":false}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -23,7 +23,7 @@ function filterRecommendationsList(
|
||||
));
|
||||
}
|
||||
|
||||
export default async function getCourseRecommendations(courseKey) {
|
||||
export async function getCourseRecommendations(courseKey) {
|
||||
const discoveryApiUrl = getConfig().DISCOVERY_API_BASE_URL;
|
||||
if (!discoveryApiUrl) {
|
||||
return [];
|
||||
@@ -36,3 +36,11 @@ export default async function getCourseRecommendations(courseKey) {
|
||||
]);
|
||||
return filterRecommendationsList(camelCaseObject(recommendationsResponse), camelCaseObject(enrollmentsResponse));
|
||||
}
|
||||
|
||||
export async function postUnsubscribeFromGoalReminders(courseId) {
|
||||
const url = new URL(`${getConfig().LMS_BASE_URL}/api/course_home/save_course_goal`);
|
||||
return getAuthenticatedHttpClient().post(url.href, {
|
||||
course_id: courseId,
|
||||
subscribed_to_reminders: false,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -5,7 +5,10 @@ import {
|
||||
fetchCourseRecommendationsRequest,
|
||||
fetchCourseRecommendationsSuccess,
|
||||
} from './slice';
|
||||
import getCourseRecommendations from './api';
|
||||
import {
|
||||
getCourseRecommendations,
|
||||
postUnsubscribeFromGoalReminders,
|
||||
} from './api';
|
||||
import { updateModel } from '../../../../generic/model-store';
|
||||
|
||||
export default function fetchCourseRecommendations(courseKey, courseId) {
|
||||
@@ -27,3 +30,7 @@ export default function fetchCourseRecommendations(courseKey, courseId) {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export async function unsubscribeFromGoalReminders(courseId, daysPerWeek, subscribedToReminders) {
|
||||
return postUnsubscribeFromGoalReminders(courseId, daysPerWeek, subscribedToReminders);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import { useModel } from '../../../generic/model-store';
|
||||
|
||||
import CourseLicense from '../course-license';
|
||||
import messages from './messages';
|
||||
import HiddenAfterDue from './hidden-after-due';
|
||||
import { SequenceNavigation, UnitNavigation } from './sequence-navigation';
|
||||
import SequenceContent from './SequenceContent';
|
||||
import NotificationTray from '../NotificationTray';
|
||||
@@ -40,14 +41,17 @@ function Sequence({
|
||||
toggleNotificationTray,
|
||||
notificationTrayVisible,
|
||||
isNotificationTrayVisible,
|
||||
notificationStatus,
|
||||
setNotificationStatus,
|
||||
onNotificationSeen,
|
||||
upgradeNotificationCurrentState,
|
||||
setupgradeNotificationCurrentState,
|
||||
mmp2p,
|
||||
}) {
|
||||
const course = useModel('coursewareMeta', courseId);
|
||||
const sequence = useModel('sequences', sequenceId);
|
||||
const unit = useModel('units', unitId);
|
||||
const sequenceStatus = useSelector(state => state.courseware.sequenceStatus);
|
||||
const specialExamsEnabledWaffleFlag = useSelector(state => state.courseware.specialExamsEnabledWaffleFlag);
|
||||
const proctoredExamsEnabledWaffleFlag = useSelector(state => state.courseware.proctoredExamsEnabledWaffleFlag);
|
||||
const shouldDisplayNotificationTrigger = useWindowSize().width < responsiveBreakpoints.small.minWidth;
|
||||
|
||||
const handleNext = () => {
|
||||
@@ -139,24 +143,10 @@ function Sequence({
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
TODO: When the micro-frontend supports viewing special exams without redirecting to the legacy
|
||||
experience, we can remove this whole conditional. For now, though, we show the spinner here
|
||||
because we expect CoursewareContainer to be performing a redirect to the legacy experience while
|
||||
we're waiting. That redirect may take a few seconds, so we show the spinner in the meantime.
|
||||
*/
|
||||
if (sequenceStatus === 'loaded') {
|
||||
const shouldRedirectSpecialExams = sequence.isTimeLimited && !specialExamsEnabledWaffleFlag;
|
||||
const shouldRedirectProctoredExams = sequence.isProctored && specialExamsEnabledWaffleFlag
|
||||
&& !proctoredExamsEnabledWaffleFlag;
|
||||
|
||||
if (shouldRedirectSpecialExams || shouldRedirectProctoredExams) {
|
||||
return (
|
||||
<PageLoading
|
||||
srMessage={intl.formatMessage(messages['learn.loading.learning.sequence'])}
|
||||
/>
|
||||
);
|
||||
}
|
||||
if (sequenceStatus === 'loaded' && sequence.isHiddenAfterDue) {
|
||||
// Shouldn't even be here - these sequences are normally stripped out of the navigation.
|
||||
// But we are here, so render a notice instead of the normal content.
|
||||
return <HiddenAfterDue courseId={courseId} />;
|
||||
}
|
||||
|
||||
const gated = sequence && sequence.gatedContent !== undefined && sequence.gatedContent.gated;
|
||||
@@ -194,6 +184,9 @@ function Sequence({
|
||||
<NotificationTrigger
|
||||
toggleNotificationTray={toggleNotificationTray}
|
||||
isNotificationTrayVisible={isNotificationTrayVisible}
|
||||
notificationStatus={notificationStatus}
|
||||
setNotificationStatus={setNotificationStatus}
|
||||
upgradeNotificationCurrentState={upgradeNotificationCurrentState}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
@@ -229,6 +222,10 @@ function Sequence({
|
||||
<NotificationTray
|
||||
toggleNotificationTray={toggleNotificationTray}
|
||||
notificationTrayVisible={notificationTrayVisible}
|
||||
notificationStatus={notificationStatus}
|
||||
onNotificationSeen={onNotificationSeen}
|
||||
upgradeNotificationCurrentState={upgradeNotificationCurrentState}
|
||||
setupgradeNotificationCurrentState={setupgradeNotificationCurrentState}
|
||||
/>
|
||||
) : null }
|
||||
|
||||
@@ -244,7 +241,12 @@ function Sequence({
|
||||
if (sequenceStatus === 'loaded') {
|
||||
return (
|
||||
<div>
|
||||
<SequenceExamWrapper sequence={sequence} courseId={courseId} isStaff={course.isStaff}>
|
||||
<SequenceExamWrapper
|
||||
sequence={sequence}
|
||||
courseId={courseId}
|
||||
isStaff={course.isStaff}
|
||||
originalUserIsStaff={course.originalUserIsStaff}
|
||||
>
|
||||
{defaultContent}
|
||||
</SequenceExamWrapper>
|
||||
<CourseLicense license={course.license || undefined} />
|
||||
@@ -271,6 +273,11 @@ Sequence.propTypes = {
|
||||
toggleNotificationTray: PropTypes.func,
|
||||
notificationTrayVisible: PropTypes.bool,
|
||||
isNotificationTrayVisible: PropTypes.func,
|
||||
notificationStatus: PropTypes.string.isRequired,
|
||||
setNotificationStatus: PropTypes.func.isRequired,
|
||||
onNotificationSeen: PropTypes.func,
|
||||
upgradeNotificationCurrentState: PropTypes.string.isRequired,
|
||||
setupgradeNotificationCurrentState: PropTypes.func.isRequired,
|
||||
|
||||
/** [MM-P2P] Experiment */
|
||||
mmp2p: PropTypes.shape({
|
||||
@@ -292,6 +299,7 @@ Sequence.defaultProps = {
|
||||
toggleNotificationTray: null,
|
||||
notificationTrayVisible: null,
|
||||
isNotificationTrayVisible: null,
|
||||
onNotificationSeen: null,
|
||||
|
||||
/** [MM-P2P] Experiment */
|
||||
mmp2p: {
|
||||
|
||||
@@ -81,11 +81,7 @@ describe('Sequence', () => {
|
||||
expect(screen.queryByText('Loading locked content messaging...')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders correctly for exam content', async () => {
|
||||
// Exams should NOT render in the Sequence. They should permanently show a spinner until the
|
||||
// application redirects away from the page. Note that this component is not responsible for
|
||||
// that redirect behavior, so there's no record of it here.
|
||||
// See CoursewareContainer.jsx "checkExamRedirect" function.
|
||||
it('renders correctly for hidden after due content', async () => {
|
||||
const sequenceBlocks = [Factory.build(
|
||||
'block',
|
||||
{ type: 'sequential', children: [unitBlocks.map(block => block.id)] },
|
||||
@@ -93,7 +89,7 @@ describe('Sequence', () => {
|
||||
)];
|
||||
const sequenceMetadata = [Factory.build(
|
||||
'sequenceMetadata',
|
||||
{ is_time_limited: true },
|
||||
{ is_hidden_after_due: true },
|
||||
{ courseId: courseMetadata.id, unitBlocks, sequenceBlock: sequenceBlocks[0] },
|
||||
)];
|
||||
const testStore = await initializeTestStore(
|
||||
@@ -101,15 +97,19 @@ describe('Sequence', () => {
|
||||
courseMetadata, unitBlocks, sequenceBlocks, sequenceMetadata,
|
||||
}, false,
|
||||
);
|
||||
const { container } = render(
|
||||
render(
|
||||
<Sequence {...mockData} {...{ sequenceId: sequenceBlocks[0].id }} />,
|
||||
{ store: testStore },
|
||||
);
|
||||
|
||||
// We expect that the sequence container isn't rendering at all.
|
||||
expect(container.querySelector('.sequence-container')).toBeNull();
|
||||
// But that we're seeing a nice spinner.
|
||||
expect(screen.queryByText('Loading learning sequence...')).toBeInTheDocument();
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByText('The due date for this assignment has passed.')).toBeInTheDocument();
|
||||
});
|
||||
expect(screen.getByRole('link', { name: 'progress page' }))
|
||||
.toHaveAttribute('href', 'http://localhost:18000/courses/course-v1:edX+DemoX+Demo_Course_1/progress');
|
||||
|
||||
// No normal content or navigation should be rendered. Just the above alert.
|
||||
expect(screen.queryAllByRole('button').length).toEqual(0);
|
||||
});
|
||||
|
||||
it('displays error message on sequence load failure', async () => {
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { injectIntl, intlShape, FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
import { Alert, Hyperlink } from '@edx/paragon';
|
||||
import { Info } from '@edx/paragon/icons';
|
||||
|
||||
import { useModel } from '../../../../generic/model-store';
|
||||
|
||||
import messages from './messages';
|
||||
|
||||
function HiddenAfterDue({ courseId, intl }) {
|
||||
const { tabs } = useModel('coursewareMeta', courseId);
|
||||
|
||||
const progressTab = tabs.find(tab => tab.slug === 'progress');
|
||||
const progressLink = progressTab && progressTab.url && (
|
||||
<Hyperlink
|
||||
style={{ textDecoration: 'underline' }}
|
||||
destination={progressTab.url}
|
||||
className="text-reset"
|
||||
>
|
||||
{intl.formatMessage(messages.progressPage)}
|
||||
</Hyperlink>
|
||||
);
|
||||
|
||||
return (
|
||||
<Alert variant="info" icon={Info}>
|
||||
<h3>{intl.formatMessage(messages.header)}</h3>
|
||||
<p>
|
||||
{intl.formatMessage(messages.description)}
|
||||
{progressLink && (
|
||||
<>
|
||||
<br />
|
||||
<FormattedMessage
|
||||
id="learn.hiddenAfterDue.gradeAvailable"
|
||||
defaultMessage="If you have completed this assignment, your grade is available on the {progressPage}."
|
||||
values={{
|
||||
progressPage: progressLink,
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</p>
|
||||
</Alert>
|
||||
);
|
||||
}
|
||||
|
||||
HiddenAfterDue.propTypes = {
|
||||
intl: intlShape.isRequired,
|
||||
courseId: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default injectIntl(HiddenAfterDue);
|
||||
1
src/courseware/course/sequence/hidden-after-due/index.js
Normal file
1
src/courseware/course/sequence/hidden-after-due/index.js
Normal file
@@ -0,0 +1 @@
|
||||
export { default } from './HiddenAfterDue';
|
||||
23
src/courseware/course/sequence/hidden-after-due/messages.js
Normal file
23
src/courseware/course/sequence/hidden-after-due/messages.js
Normal file
@@ -0,0 +1,23 @@
|
||||
import { defineMessages } from '@edx/frontend-platform/i18n';
|
||||
|
||||
const messages = defineMessages({
|
||||
header: {
|
||||
id: 'learn.hiddenAfterDue.header',
|
||||
defaultMessage: 'The due date for this assignment has passed.',
|
||||
},
|
||||
description: {
|
||||
id: 'learn.hiddenAfterDue.description',
|
||||
defaultMessage: 'Because the due date has passed, this assignment is no longer available.',
|
||||
},
|
||||
gradeAvailable: {
|
||||
id: 'learn.hiddenAfterDue.gradeAvailable',
|
||||
defaultMessage: 'If you have completed this assignment, your grade is available on the {progressPage}.',
|
||||
},
|
||||
progressPage: {
|
||||
id: 'learn.hiddenAfterDue.progressPage',
|
||||
defaultMessage: 'progress page',
|
||||
description: 'This is the text for the link embedded in learn.hiddenAfterDue.gradeAvailable',
|
||||
},
|
||||
});
|
||||
|
||||
export default messages;
|
||||
@@ -5,19 +5,19 @@ import { getConfig, history } from '@edx/frontend-platform';
|
||||
import { FormattedMessage, injectIntl, intlShape } from '@edx/frontend-platform/i18n';
|
||||
import { ActionRow, Alert, Button } from '@edx/paragon';
|
||||
|
||||
import { useModel } from '../../../../generic/model-store';
|
||||
import { saveIntegritySignature } from '../../../data';
|
||||
import messages from './messages';
|
||||
|
||||
function HonorCode({ intl, courseId }) {
|
||||
const dispatch = useDispatch();
|
||||
const { isMasquerading } = useModel('coursewareMeta', courseId);
|
||||
const siteName = getConfig().SITE_NAME;
|
||||
const honorCodeUrl = `${process.env.TERMS_OF_SERVICE_URL}#honor-code`;
|
||||
const honorCodeUrl = `${getConfig().TERMS_OF_SERVICE_URL}#honor-code`;
|
||||
|
||||
const handleCancel = () => history.push(`/course/${courseId}/home`);
|
||||
|
||||
const handleAgree = () => {
|
||||
dispatch(saveIntegritySignature(courseId));
|
||||
};
|
||||
const handleAgree = () => dispatch(saveIntegritySignature(courseId, isMasquerading));
|
||||
|
||||
return (
|
||||
<Alert variant="light" aria-live="off">
|
||||
|
||||
@@ -113,7 +113,7 @@ function LockPaywall({
|
||||
<span className="fa-li"><FontAwesomeIcon icon={faCheck} /></span>
|
||||
<FormattedMessage
|
||||
id="gatedContent.paragraph.bulletOne"
|
||||
defaultMessage="Earn a {verifiedCertLink} of completion to showcase on your resume"
|
||||
defaultMessage="Earn a {verifiedCertLink} of completion to showcase on your resumé"
|
||||
values={{ verifiedCertLink }}
|
||||
className="bullet-text"
|
||||
/>
|
||||
@@ -149,7 +149,7 @@ function LockPaywall({
|
||||
|
||||
<div
|
||||
className={
|
||||
classNames('p-md-0 d-md-flex align-items-md-center text-right', {
|
||||
classNames('d-md-flex align-items-md-center text-right', {
|
||||
'col-md-5 mx-md-0': notificationTrayVisible, 'col-md-4 mx-md-3 justify-content-center': !notificationTrayVisible && !shouldDisplayGatedContentTwoColumnsHalf, 'col-md-11 justify-content-end': shouldDisplayGatedContentOneColumn && !shouldDisplayGatedContentTwoColumns, 'col-md-6 justify-content-center': shouldDisplayGatedContentTwoColumnsHalf,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
.alert-content.lock-paywall-container {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.lock-paywall-container svg {
|
||||
color: $primary-700;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,13 @@ Factory.define('courseMetadata')
|
||||
.attrs({
|
||||
content_type_gating_enabled: false,
|
||||
course_expired_message: null,
|
||||
course_goals: {
|
||||
goal_options: [],
|
||||
selected_goal: {
|
||||
days_per_week: 1,
|
||||
subscribed_to_reminders: true,
|
||||
},
|
||||
},
|
||||
end: null,
|
||||
enrollment_start: null,
|
||||
enrollment_end: null,
|
||||
@@ -55,7 +62,5 @@ Factory.define('courseMetadata')
|
||||
linkedin_add_to_profile_url: null,
|
||||
related_programs: null,
|
||||
user_needs_integrity_signature: false,
|
||||
is_mfe_special_exams_enabled: false,
|
||||
is_mfe_proctored_exams_enabled: false,
|
||||
recommendations: null,
|
||||
});
|
||||
|
||||
@@ -58,6 +58,7 @@ Factory.define('sequenceMetadata')
|
||||
save_position: true,
|
||||
prev_url: null,
|
||||
is_time_limited: false,
|
||||
is_hidden_after_due: false,
|
||||
show_completion: true,
|
||||
banner_text: null,
|
||||
format: 'Homework',
|
||||
|
||||
@@ -187,6 +187,7 @@ function normalizeMetadata(metadata) {
|
||||
accessExpiration: camelCaseObject(data.access_expiration),
|
||||
canShowUpgradeSock: data.can_show_upgrade_sock,
|
||||
contentTypeGatingEnabled: data.content_type_gating_enabled,
|
||||
courseGoals: data.course_goals,
|
||||
id: data.id,
|
||||
title: data.name,
|
||||
number: data.number,
|
||||
@@ -219,8 +220,6 @@ function normalizeMetadata(metadata) {
|
||||
linkedinAddToProfileUrl: data.linkedin_add_to_profile_url,
|
||||
relatedPrograms: camelCaseObject(data.related_programs),
|
||||
userNeedsIntegritySignature: data.user_needs_integrity_signature,
|
||||
specialExamsEnabledWaffleFlag: data.is_mfe_special_exams_enabled,
|
||||
proctoredExamsEnabledWaffleFlag: data.is_mfe_proctored_exams_enabled,
|
||||
isMasquerading: data.original_user_is_staff && !data.is_staff,
|
||||
};
|
||||
}
|
||||
@@ -253,6 +252,7 @@ function normalizeSequenceMetadata(sequence) {
|
||||
gatedContent: camelCaseObject(sequence.gated_content),
|
||||
isTimeLimited: sequence.is_time_limited,
|
||||
isProctored: sequence.is_proctored,
|
||||
isHiddenAfterDue: sequence.is_hidden_after_due,
|
||||
// Position comes back from the server 1-indexed. Adjust here.
|
||||
activeUnitIndex: sequence.position ? sequence.position - 1 : 0,
|
||||
saveUnitPosition: sequence.save_position,
|
||||
|
||||
@@ -4,9 +4,19 @@ import { mergeConfig, getConfig } from '@edx/frontend-platform';
|
||||
import { getAuthenticatedUser } from '@edx/frontend-platform/auth';
|
||||
|
||||
import {
|
||||
getCourseBlocks, getCourseMetadata, getSequenceMetadata, postSequencePosition, getBlockCompletion,
|
||||
getCourseBlocks,
|
||||
getCourseMetadata,
|
||||
getSequenceMetadata,
|
||||
postSequencePosition,
|
||||
getBlockCompletion,
|
||||
getResumeBlock,
|
||||
sendActivationEmail,
|
||||
} from '../api';
|
||||
|
||||
import { initializeMockApp } from '../../../setupTest';
|
||||
import {
|
||||
courseId, dateRegex, opaqueKeysRegex, sequenceId, usageId,
|
||||
} from '../../../pacts/constants';
|
||||
|
||||
const {
|
||||
somethingLike: like, term, boolean, string, eachLike, integer,
|
||||
@@ -15,17 +25,13 @@ const provider = new Pact({
|
||||
consumer: 'frontend-app-learning',
|
||||
provider: 'lms',
|
||||
log: path.resolve(process.cwd(), 'src/courseware/data/pact-tests/logs', 'pact.log'),
|
||||
dir: path.resolve(process.cwd(), 'src/courseware/data/pact-tests'),
|
||||
dir: path.resolve(process.cwd(), 'src/pacts'),
|
||||
pactfileWriteMode: 'merge',
|
||||
logLevel: 'DEBUG',
|
||||
cors: true,
|
||||
});
|
||||
|
||||
describe('Courseware Service', () => {
|
||||
const courseId = 'course-v1:edX+DemoX+Demo_Course';
|
||||
const sequenceId = 'block-v1:edX+DemoX+Demo_Course+type@sequential+block@basic_questions';
|
||||
const usageId = 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@47dbd5f836544e61877a483c0b75606c';
|
||||
const dateRegex = '^(?:[1-9]\\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)T(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:Z|[+-][01]\\d:[0-5]\\d)$';
|
||||
const opaqueKeysRegex = '[\\w\\-~.:]';
|
||||
let authenticatedUser;
|
||||
beforeAll(async () => {
|
||||
initializeMockApp();
|
||||
@@ -57,8 +63,7 @@ describe('Courseware Service', () => {
|
||||
},
|
||||
willRespondWith: {
|
||||
status: 200,
|
||||
body:
|
||||
{
|
||||
body: {
|
||||
root: string('block-v1:edX+DemoX+Demo_Course+type@course+block@course'),
|
||||
blocks: like({
|
||||
'block-v1:edX+DemoX+Demo_Course+type@course+block@course': {
|
||||
@@ -105,8 +110,7 @@ describe('Courseware Service', () => {
|
||||
},
|
||||
willRespondWith: {
|
||||
status: 200,
|
||||
body:
|
||||
{
|
||||
body: {
|
||||
access_expiration: {
|
||||
expiration_date: term({
|
||||
generate: '2013-02-05T05:00:00Z',
|
||||
@@ -170,7 +174,10 @@ describe('Courseware Service', () => {
|
||||
}),
|
||||
user_timezone: null,
|
||||
verified_mode: like({
|
||||
access_expiration_date: null,
|
||||
access_expiration_date: term({
|
||||
generate: '2013-02-05T05:00:00Z',
|
||||
matcher: dateRegex,
|
||||
}),
|
||||
currency: 'USD',
|
||||
currency_symbol: '$',
|
||||
price: 149,
|
||||
@@ -182,7 +189,7 @@ describe('Courseware Service', () => {
|
||||
can_view_legacy_courseware: boolean(true),
|
||||
is_staff: boolean(true),
|
||||
course_access: like({
|
||||
has_access: boolean(true),
|
||||
has_access: true,
|
||||
error_code: null,
|
||||
developer_message: null,
|
||||
user_message: null,
|
||||
@@ -192,9 +199,9 @@ describe('Courseware Service', () => {
|
||||
notes: { enabled: boolean(false), visible: boolean(true) },
|
||||
marketing_url: null,
|
||||
celebrations: {
|
||||
irst_section: boolean(false),
|
||||
first_section: boolean(false),
|
||||
streak_length_to_celebrate: null,
|
||||
streak_discount_experiment_enabled: boolean(false),
|
||||
streak_discount_enabled: boolean(false),
|
||||
},
|
||||
user_has_passing_grade: boolean(false),
|
||||
course_exit_page_is_active: boolean(false),
|
||||
@@ -204,8 +211,6 @@ describe('Courseware Service', () => {
|
||||
verify_identity_url: null,
|
||||
verification_status: string('none'),
|
||||
linkedin_add_to_profile_url: null,
|
||||
is_mfe_special_exams_enabled: boolean(false),
|
||||
is_mfe_proctored_exams_enabled: boolean(false),
|
||||
user_needs_integrity_signature: boolean(false),
|
||||
},
|
||||
},
|
||||
@@ -251,30 +256,28 @@ describe('Courseware Service', () => {
|
||||
isStaff: true,
|
||||
license: 'all-rights-reserved',
|
||||
verifiedMode: {
|
||||
accessExpirationDate: null,
|
||||
accessExpirationDate: '2013-02-05T05:00:00Z',
|
||||
currency: 'USD',
|
||||
currencySymbol: '$',
|
||||
price: 149,
|
||||
sku: '8CF08E5',
|
||||
upgradeUrl: `${getConfig().ECOMMERCE_BASE_URL}/basket/add/?sku=8CF08E5`,
|
||||
},
|
||||
tabs: [
|
||||
{
|
||||
title: 'Course',
|
||||
slug: 'courseware',
|
||||
priority: 0,
|
||||
type: 'courseware',
|
||||
url: `${getConfig().BASE_URL}/course/course-v1:edX+DemoX+Demo_Course/home`,
|
||||
},
|
||||
],
|
||||
tabs: [{
|
||||
title: 'Course',
|
||||
slug: 'courseware',
|
||||
priority: 0,
|
||||
type: 'courseware',
|
||||
url: `${getConfig().BASE_URL}/course/course-v1:edX+DemoX+Demo_Course/home`,
|
||||
}],
|
||||
userTimezone: null,
|
||||
showCalculator: false,
|
||||
notes: { enabled: false, visible: true },
|
||||
marketingUrl: null,
|
||||
celebrations: {
|
||||
irstSection: false,
|
||||
firstSection: false,
|
||||
streakLengthToCelebrate: null,
|
||||
streakDiscountExperimentEnabled: false,
|
||||
streakDiscountEnabled: false,
|
||||
},
|
||||
userHasPassingGrade: false,
|
||||
courseExitPageIsActive: false,
|
||||
@@ -290,8 +293,6 @@ describe('Courseware Service', () => {
|
||||
linkedinAddToProfileUrl: null,
|
||||
relatedPrograms: null,
|
||||
userNeedsIntegritySignature: false,
|
||||
specialExamsEnabledWaffleFlag: false,
|
||||
proctoredExamsEnabledWaffleFlag: false,
|
||||
isMasquerading: false,
|
||||
};
|
||||
const response = await getCourseMetadata(courseId);
|
||||
@@ -311,8 +312,7 @@ describe('Courseware Service', () => {
|
||||
},
|
||||
willRespondWith: {
|
||||
status: 200,
|
||||
body:
|
||||
{
|
||||
body: {
|
||||
items: eachLike({
|
||||
content: '',
|
||||
page_title: 'Pointing on a Picture',
|
||||
@@ -327,6 +327,7 @@ describe('Courseware Service', () => {
|
||||
item_id: string('block-v1:edX+DemoX+Demo_Course+type@sequential+block@basic_questions'),
|
||||
is_time_limited: boolean(false),
|
||||
is_proctored: boolean(false),
|
||||
is_hidden_after_due: boolean(false),
|
||||
position: null,
|
||||
tag: boolean('sequential'),
|
||||
banner_text: null,
|
||||
@@ -363,23 +364,22 @@ describe('Courseware Service', () => {
|
||||
},
|
||||
isTimeLimited: false,
|
||||
isProctored: false,
|
||||
isHiddenAfterDue: false,
|
||||
activeUnitIndex: 0,
|
||||
saveUnitPosition: false,
|
||||
showCompletion: false,
|
||||
allowProctoringOptOut: undefined,
|
||||
},
|
||||
units: [
|
||||
{
|
||||
id: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@2152d4a4aadc4cb0af5256394a3d1fc7',
|
||||
sequenceId: 'block-v1:edX+DemoX+Demo_Course+type@sequential+block@basic_questions',
|
||||
bookmarked: false,
|
||||
complete: undefined,
|
||||
title: 'Pointing on a Picture',
|
||||
contentType: 'problem',
|
||||
graded: true,
|
||||
containsContentTypeGatedContent: false,
|
||||
},
|
||||
],
|
||||
units: [{
|
||||
id: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@2152d4a4aadc4cb0af5256394a3d1fc7',
|
||||
sequenceId: 'block-v1:edX+DemoX+Demo_Course+type@sequential+block@basic_questions',
|
||||
bookmarked: false,
|
||||
complete: undefined,
|
||||
title: 'Pointing on a Picture',
|
||||
contentType: 'problem',
|
||||
graded: true,
|
||||
containsContentTypeGatedContent: false,
|
||||
}],
|
||||
};
|
||||
const response = await getSequenceMetadata(sequenceId);
|
||||
expect(response).toBeTruthy();
|
||||
@@ -399,8 +399,7 @@ describe('Courseware Service', () => {
|
||||
},
|
||||
willRespondWith: {
|
||||
status: 200,
|
||||
body:
|
||||
{
|
||||
body: {
|
||||
success: boolean(true),
|
||||
},
|
||||
},
|
||||
@@ -423,8 +422,7 @@ describe('Courseware Service', () => {
|
||||
},
|
||||
willRespondWith: {
|
||||
status: 200,
|
||||
body:
|
||||
{
|
||||
body: {
|
||||
complete: boolean(true),
|
||||
},
|
||||
},
|
||||
@@ -434,4 +432,51 @@ describe('Courseware Service', () => {
|
||||
expect(response).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('When a request to get resume block is made', () => {
|
||||
it('returns block id, section id and unit id of the resume block', async () => {
|
||||
await provider.addInteraction({
|
||||
state: `Resume block exists for course_id ${courseId}`,
|
||||
uponReceiving: 'a request to get Resume block',
|
||||
withRequest: {
|
||||
method: 'GET',
|
||||
path: `/api/courseware/resume/${courseId}`,
|
||||
},
|
||||
willRespondWith: {
|
||||
status: 200,
|
||||
body: {
|
||||
block_id: string('642fadf46d074aabb637f20af320fb31'),
|
||||
section_id: string('642fadf46d074aabb637f20af320fb87'),
|
||||
unit_id: string('642fadf46d074aabb637f20af320fb99'),
|
||||
},
|
||||
},
|
||||
});
|
||||
const camelCaseResponse = {
|
||||
blockId: '642fadf46d074aabb637f20af320fb31',
|
||||
sectionId: '642fadf46d074aabb637f20af320fb87',
|
||||
unitId: '642fadf46d074aabb637f20af320fb99',
|
||||
};
|
||||
const response = await getResumeBlock(courseId);
|
||||
expect(response).toBeTruthy();
|
||||
expect(response).toEqual(camelCaseResponse);
|
||||
});
|
||||
});
|
||||
|
||||
describe('When a request to send activation email is made', () => {
|
||||
it('returns status code 200', async () => {
|
||||
await provider.addInteraction({
|
||||
state: 'A logged-in user may or may not be active',
|
||||
uponReceiving: 'a request to send activation email',
|
||||
withRequest: {
|
||||
method: 'POST',
|
||||
path: '/api/send_account_activation_email',
|
||||
},
|
||||
willRespondWith: {
|
||||
status: 200,
|
||||
},
|
||||
});
|
||||
const response = await sendActivationEmail();
|
||||
expect(response).toEqual('');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -13,16 +13,8 @@ const slice = createSlice({
|
||||
courseId: null,
|
||||
sequenceStatus: 'loading',
|
||||
sequenceId: null,
|
||||
specialExamsEnabledWaffleFlag: false,
|
||||
proctoredExamsEnabledWaffleFlag: false,
|
||||
},
|
||||
reducers: {
|
||||
setsSpecialExamsEnabled: (state, { payload }) => {
|
||||
state.specialExamsEnabledWaffleFlag = payload.specialExamsEnabledWaffleFlag;
|
||||
},
|
||||
setsProctoredExamsEnabled: (state, { payload }) => {
|
||||
state.proctoredExamsEnabledWaffleFlag = payload.proctoredExamsEnabledWaffleFlag;
|
||||
},
|
||||
fetchCourseRequest: (state, { payload }) => {
|
||||
state.courseId = payload.courseId;
|
||||
state.courseStatus = LOADING;
|
||||
@@ -55,8 +47,6 @@ const slice = createSlice({
|
||||
});
|
||||
|
||||
export const {
|
||||
setsSpecialExamsEnabled,
|
||||
setsProctoredExamsEnabled,
|
||||
fetchCourseRequest,
|
||||
fetchCourseSuccess,
|
||||
fetchCourseFailure,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { logError } from '@edx/frontend-platform/logging';
|
||||
import { logError, logInfo } from '@edx/frontend-platform/logging';
|
||||
import {
|
||||
getBlockCompletion,
|
||||
postSequencePosition,
|
||||
@@ -12,8 +12,6 @@ import {
|
||||
updateModel, addModel, updateModelsMap, addModelsMap, updateModels,
|
||||
} from '../../generic/model-store';
|
||||
import {
|
||||
setsSpecialExamsEnabled,
|
||||
setsProctoredExamsEnabled,
|
||||
fetchCourseRequest,
|
||||
fetchCourseSuccess,
|
||||
fetchCourseFailure,
|
||||
@@ -145,12 +143,6 @@ export function fetchCourse(courseId) {
|
||||
modelType: 'coursewareMeta',
|
||||
model: courseMetadataResult.value,
|
||||
}));
|
||||
dispatch(setsSpecialExamsEnabled({
|
||||
specialExamsEnabledWaffleFlag: courseMetadataResult.value.specialExamsEnabledWaffleFlag,
|
||||
}));
|
||||
dispatch(setsProctoredExamsEnabled({
|
||||
proctoredExamsEnabledWaffleFlag: courseMetadataResult.value.proctoredExamsEnabledWaffleFlag,
|
||||
}));
|
||||
}
|
||||
|
||||
if (courseBlocksResult.status === 'fulfilled') {
|
||||
@@ -188,7 +180,14 @@ export function fetchCourse(courseId) {
|
||||
// Log errors for each request if needed. Course block failures may occur
|
||||
// even if the course metadata request is successful
|
||||
if (!fetchedBlocks) {
|
||||
logError(courseBlocksResult.reason);
|
||||
const { response } = courseBlocksResult.reason;
|
||||
if (response && response.status === 403) {
|
||||
// 403 responses are normal - they happen when the learner is logged out.
|
||||
// We'll redirect them in a moment to the outline tab by calling fetchCourseDenied() below.
|
||||
logInfo(courseBlocksResult.reason);
|
||||
} else {
|
||||
logError(courseBlocksResult.reason);
|
||||
}
|
||||
}
|
||||
if (!fetchedMetadata) {
|
||||
logError(courseMetadataResult.reason);
|
||||
@@ -248,7 +247,7 @@ export function checkBlockCompletion(courseId, sequenceId, unitId) {
|
||||
return async (dispatch, getState) => {
|
||||
const { models } = getState();
|
||||
if (models.units[unitId].complete) {
|
||||
return; // do nothing. Things don't get uncompleted after they are completed.
|
||||
return {}; // do nothing. Things don't get uncompleted after they are completed.
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -260,9 +259,11 @@ export function checkBlockCompletion(courseId, sequenceId, unitId) {
|
||||
complete: isComplete,
|
||||
},
|
||||
}));
|
||||
return isComplete;
|
||||
} catch (error) {
|
||||
logError(error);
|
||||
}
|
||||
return {};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -302,10 +303,15 @@ export function saveSequencePosition(courseId, sequenceId, activeUnitIndex) {
|
||||
};
|
||||
}
|
||||
|
||||
export function saveIntegritySignature(courseId) {
|
||||
export function saveIntegritySignature(courseId, isMasquerading) {
|
||||
return async (dispatch) => {
|
||||
try {
|
||||
await postIntegritySignature(courseId);
|
||||
// If the request is made by a staff user masquerading as a learner,
|
||||
// don't actually create a signature for them on the backend. Only
|
||||
// frontend state will be updated.
|
||||
if (!isMasquerading) {
|
||||
await postIntegritySignature(courseId);
|
||||
}
|
||||
dispatch(updateModel({
|
||||
modelType: 'coursewareMeta',
|
||||
model: {
|
||||
|
||||
@@ -48,7 +48,7 @@ export const BlockModal = () => (
|
||||
|
||||
<div>
|
||||
<BulletList>
|
||||
Earn a verified certificate of completion to showcase on your resume
|
||||
Earn a verified certificate of completion to showcase on your resumé
|
||||
</BulletList>
|
||||
<BulletList>
|
||||
Unlock unlimited access to all course content and activities,
|
||||
|
||||
@@ -103,7 +103,7 @@ const Sidecard = ({
|
||||
<span style={{ fontWeight: 600 }}>graded assignments</span>
|
||||
</BulletList>
|
||||
<BulletList>
|
||||
Earn a {certLink} of completion to showcase on your resume
|
||||
Earn a {certLink} of completion to showcase on your resumé
|
||||
</BulletList>
|
||||
<BulletList>
|
||||
Support our <span style={{ fontWeight: 600 }}>non-profit mission</span> at edX
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { Spinner } from '@edx/paragon';
|
||||
|
||||
export default class PageLoading extends Component {
|
||||
renderSrMessage() {
|
||||
if (!this.props.srMessage) {
|
||||
@@ -23,9 +25,9 @@ export default class PageLoading extends Component {
|
||||
height: '50vh',
|
||||
}}
|
||||
>
|
||||
<div className="spinner-border text-primary" role="status">
|
||||
<Spinner animation="border" variant="primary" role="status">
|
||||
{this.renderSrMessage()}
|
||||
</div>
|
||||
</Spinner>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
35
src/generic/notices/NoticesProvider.jsx
Normal file
35
src/generic/notices/NoticesProvider.jsx
Normal file
@@ -0,0 +1,35 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import PropTypes from 'prop-types';
|
||||
import { getNotices } from './api';
|
||||
/**
|
||||
* This component uses the platform-plugin-notices plugin to function.
|
||||
* If the user has an unacknowledged notice, they will be rerouted off
|
||||
* course home and onto a full-screen notice page. If the plugin is not
|
||||
* installed, or there are no notices, we just passthrough this component.
|
||||
*/
|
||||
const NoticesProvider = ({ children }) => {
|
||||
const [isRedirected, setIsRedirected] = useState();
|
||||
useEffect(async () => {
|
||||
if (getConfig().ENABLE_NOTICES) {
|
||||
const data = await getNotices();
|
||||
if (data && data.results && data.results.length > 0) {
|
||||
const { results } = data;
|
||||
setIsRedirected(true);
|
||||
window.location.replace(`${results[0]}?next=${window.location.href}`);
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div>
|
||||
{isRedirected === true ? null : children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
NoticesProvider.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
};
|
||||
|
||||
export default NoticesProvider;
|
||||
61
src/generic/notices/NoticesProvider.test.jsx
Normal file
61
src/generic/notices/NoticesProvider.test.jsx
Normal file
@@ -0,0 +1,61 @@
|
||||
import React from 'react';
|
||||
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import {
|
||||
initializeMockApp,
|
||||
render,
|
||||
act,
|
||||
} from '../../setupTest';
|
||||
import NoticesProvider from './NoticesProvider';
|
||||
import { getNotices } from './api';
|
||||
|
||||
jest.mock('./api', () => ({
|
||||
getNotices: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('@edx/frontend-platform', () => ({
|
||||
getConfig: jest.fn(),
|
||||
}));
|
||||
|
||||
describe('NoticesProvider', () => {
|
||||
beforeAll(async () => {
|
||||
jest.resetModules();
|
||||
await initializeMockApp();
|
||||
});
|
||||
|
||||
function buildAndRender() {
|
||||
render(
|
||||
<NoticesProvider>
|
||||
<div />
|
||||
</NoticesProvider>,
|
||||
);
|
||||
}
|
||||
|
||||
it('does not call api if ENABLE_NOTICES is false', () => {
|
||||
getConfig.mockImplementation(() => ({ ENABLE_NOTICES: false }));
|
||||
buildAndRender();
|
||||
expect(getNotices).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
it('redirects user on notice returned from API', async () => {
|
||||
const redirectUrl = 'http://example.com/test_route';
|
||||
getConfig.mockImplementation(() => ({ ENABLE_NOTICES: true }));
|
||||
getNotices.mockImplementation(() => ({ results: [redirectUrl] }));
|
||||
delete window.location;
|
||||
window.location = { replace: jest.fn() };
|
||||
process.env.ENABLE_NOTICES = true;
|
||||
await act(async () => buildAndRender());
|
||||
expect(window.location.replace).toHaveBeenCalledWith(`${redirectUrl}?next=${window.location.href}`);
|
||||
});
|
||||
|
||||
it('does not redirect on no data', async () => {
|
||||
getNotices.mockImplementation(() => ({}));
|
||||
getConfig.mockImplementation(() => ({ ENABLE_NOTICES: true }));
|
||||
delete window.location;
|
||||
window.location = { replace: jest.fn() };
|
||||
process.env.ENABLE_NOTICES = true;
|
||||
await act(async () => buildAndRender());
|
||||
expect(window.location.replace).toHaveBeenCalledTimes(0);
|
||||
expect(window.location.toString() === 'http://localhost/');
|
||||
});
|
||||
});
|
||||
25
src/generic/notices/api.js
Normal file
25
src/generic/notices/api.js
Normal file
@@ -0,0 +1,25 @@
|
||||
/* eslint-disable import/prefer-default-export */
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import { getAuthenticatedHttpClient, getAuthenticatedUser } from '@edx/frontend-platform/auth';
|
||||
import { logError, logInfo } from '@edx/frontend-platform/logging';
|
||||
|
||||
export const getNotices = async () => {
|
||||
const authenticatedUser = getAuthenticatedUser();
|
||||
const url = new URL(`${getConfig().LMS_BASE_URL}/notices/api/v1/unacknowledged`);
|
||||
if (authenticatedUser) {
|
||||
try {
|
||||
const { data } = await getAuthenticatedHttpClient().get(url.href, {});
|
||||
return data;
|
||||
} catch (e) {
|
||||
// we will just swallow error, as that probably means the notices app is not installed.
|
||||
// Notices are not necessary for the rest of courseware to function.
|
||||
const { customAttributes: { httpErrorStatus } } = e;
|
||||
if (httpErrorStatus === 404) {
|
||||
logInfo(`${e}. This probably happened because the notices plugin is not installed on platform.`);
|
||||
} else {
|
||||
logError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
1
src/generic/notices/index.js
Normal file
1
src/generic/notices/index.js
Normal file
@@ -0,0 +1 @@
|
||||
export { default } from './NoticesProvider';
|
||||
@@ -7,6 +7,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { sendTrackEvent, sendTrackingLogEvent } from '@edx/frontend-platform/analytics';
|
||||
import { FormattedDate, FormattedMessage, injectIntl } from '@edx/frontend-platform/i18n';
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import { setLocalStorage } from '../../data/localStorage';
|
||||
|
||||
import { UpgradeButton } from '../upgrade-button';
|
||||
|
||||
@@ -26,7 +27,7 @@ function UpsellNoFBECardContent() {
|
||||
<span className="fa-li upgrade-notification-li"><FontAwesomeIcon icon={faCheck} /></span>
|
||||
<FormattedMessage
|
||||
id="learning.generic.upgradeNotification.verifiedCertMessage"
|
||||
defaultMessage="Earn a {verifiedCertLink} of completion to showcase on your resume"
|
||||
defaultMessage="Earn a {verifiedCertLink} of completion to showcase on your resumé"
|
||||
values={{ verifiedCertLink }}
|
||||
/>
|
||||
</li>
|
||||
@@ -89,7 +90,7 @@ function UpsellFBEFarAwayCardContent() {
|
||||
<span className="fa-li upgrade-notification-li"><FontAwesomeIcon icon={faCheck} /></span>
|
||||
<FormattedMessage
|
||||
id="learning.generic.upgradeNotification.verifiedCertMessage"
|
||||
defaultMessage="Earn a {verifiedCertLink} of completion to showcase on your resume"
|
||||
defaultMessage="Earn a {verifiedCertLink} of completion to showcase on your resumé"
|
||||
values={{ verifiedCertLink }}
|
||||
/>
|
||||
</li>
|
||||
@@ -184,10 +185,20 @@ UpsellFBESoonCardContent.defaultProps = {
|
||||
timezoneFormatArgs: {},
|
||||
};
|
||||
|
||||
function ExpirationCountdown({ hoursToExpiration }) {
|
||||
function ExpirationCountdown({ hoursToExpiration, setupgradeNotificationCurrentState, type }) {
|
||||
let expirationText;
|
||||
|
||||
if (hoursToExpiration >= 24) {
|
||||
// setupgradeNotificationCurrentState is available in NotificationTray (not course home)
|
||||
if (setupgradeNotificationCurrentState) {
|
||||
if (type === 'access') {
|
||||
setupgradeNotificationCurrentState('accessDaysLeft');
|
||||
setLocalStorage('upgradeNotificationCurrentState', 'accessDaysLeft');
|
||||
}
|
||||
if (type === 'offer') {
|
||||
setupgradeNotificationCurrentState('FPDdaysLeft');
|
||||
setLocalStorage('upgradeNotificationCurrentState', 'FPDdaysLeft');
|
||||
}
|
||||
}
|
||||
expirationText = (
|
||||
<FormattedMessage
|
||||
id="learning.generic.upgradeNotification.expirationDays"
|
||||
@@ -200,6 +211,17 @@ function ExpirationCountdown({ hoursToExpiration }) {
|
||||
/>
|
||||
);
|
||||
} else if (hoursToExpiration >= 1) {
|
||||
// setupgradeNotificationCurrentState is available in NotificationTray (not course home)
|
||||
if (setupgradeNotificationCurrentState) {
|
||||
if (type === 'access') {
|
||||
setupgradeNotificationCurrentState('accessHoursLeft');
|
||||
setLocalStorage('upgradeNotificationCurrentState', 'accessHoursLeft');
|
||||
}
|
||||
if (type === 'offer') {
|
||||
setupgradeNotificationCurrentState('FPDHoursLeft');
|
||||
setLocalStorage('upgradeNotificationCurrentState', 'FPDHoursLeft');
|
||||
}
|
||||
}
|
||||
expirationText = (
|
||||
<FormattedMessage
|
||||
id="learning.generic.upgradeNotification.expirationHours"
|
||||
@@ -212,6 +234,17 @@ function ExpirationCountdown({ hoursToExpiration }) {
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
// setupgradeNotificationCurrentState is available in NotificationTray (not course home)
|
||||
if (setupgradeNotificationCurrentState) {
|
||||
if (type === 'access') {
|
||||
setupgradeNotificationCurrentState('accessLastHour');
|
||||
setLocalStorage('upgradeNotificationCurrentState', 'accessLastHour');
|
||||
}
|
||||
if (type === 'offer') {
|
||||
setupgradeNotificationCurrentState('FPDLastHour');
|
||||
setLocalStorage('upgradeNotificationCurrentState', 'FPDLastHour');
|
||||
}
|
||||
}
|
||||
expirationText = (
|
||||
<FormattedMessage
|
||||
id="learning.generic.upgradeNotification.expirationMinutes"
|
||||
@@ -224,9 +257,19 @@ function ExpirationCountdown({ hoursToExpiration }) {
|
||||
|
||||
ExpirationCountdown.propTypes = {
|
||||
hoursToExpiration: PropTypes.number.isRequired,
|
||||
setupgradeNotificationCurrentState: PropTypes.func,
|
||||
type: PropTypes.string,
|
||||
};
|
||||
ExpirationCountdown.defaultProps = {
|
||||
setupgradeNotificationCurrentState: null,
|
||||
type: null,
|
||||
};
|
||||
|
||||
function AccessExpirationDateBanner({ accessExpirationDate, timezoneFormatArgs }) {
|
||||
function AccessExpirationDateBanner({ accessExpirationDate, timezoneFormatArgs, setupgradeNotificationCurrentState }) {
|
||||
if (setupgradeNotificationCurrentState) {
|
||||
setupgradeNotificationCurrentState('accessDateView');
|
||||
setLocalStorage('upgradeNotificationCurrentState', 'accessDateView');
|
||||
}
|
||||
return (
|
||||
<div className="upsell-warning-light">
|
||||
<FormattedMessage
|
||||
@@ -253,10 +296,12 @@ AccessExpirationDateBanner.propTypes = {
|
||||
timezoneFormatArgs: PropTypes.shape({
|
||||
timeZone: PropTypes.string,
|
||||
}),
|
||||
setupgradeNotificationCurrentState: PropTypes.func,
|
||||
};
|
||||
|
||||
AccessExpirationDateBanner.defaultProps = {
|
||||
timezoneFormatArgs: {},
|
||||
setupgradeNotificationCurrentState: null,
|
||||
};
|
||||
|
||||
function UpgradeNotification({
|
||||
@@ -265,6 +310,7 @@ function UpgradeNotification({
|
||||
courseId,
|
||||
offer,
|
||||
org,
|
||||
setupgradeNotificationCurrentState,
|
||||
shouldDisplayBorder,
|
||||
timeOffsetMillis,
|
||||
upsellPageName,
|
||||
@@ -340,7 +386,13 @@ function UpgradeNotification({
|
||||
}}
|
||||
/>
|
||||
);
|
||||
expirationBanner = <ExpirationCountdown hoursToExpiration={hoursToDiscountExpiration} />;
|
||||
expirationBanner = (
|
||||
<ExpirationCountdown
|
||||
hoursToExpiration={hoursToDiscountExpiration}
|
||||
setupgradeNotificationCurrentState={setupgradeNotificationCurrentState}
|
||||
type="offer"
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
upgradeNotificationHeaderText = (
|
||||
<FormattedMessage
|
||||
@@ -352,6 +404,7 @@ function UpgradeNotification({
|
||||
<AccessExpirationDateBanner
|
||||
accessExpirationDate={accessExpirationDate}
|
||||
timezoneFormatArgs={timezoneFormatArgs}
|
||||
setupgradeNotificationCurrentState={setupgradeNotificationCurrentState}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -363,7 +416,13 @@ function UpgradeNotification({
|
||||
defaultMessage="Course Access Expiration"
|
||||
/>
|
||||
);
|
||||
expirationBanner = <ExpirationCountdown hoursToExpiration={hoursToAccessExpiration} />;
|
||||
expirationBanner = (
|
||||
<ExpirationCountdown
|
||||
hoursToExpiration={hoursToAccessExpiration}
|
||||
setupgradeNotificationCurrentState={setupgradeNotificationCurrentState}
|
||||
type="access"
|
||||
/>
|
||||
);
|
||||
upsellMessage = (
|
||||
<UpsellFBESoonCardContent
|
||||
accessExpirationDate={accessExpirationDate}
|
||||
@@ -404,13 +463,14 @@ function UpgradeNotification({
|
||||
<div className="upgrade-notification-message">
|
||||
{upsellMessage}
|
||||
</div>
|
||||
<UpgradeButton
|
||||
offer={offer}
|
||||
onClick={logClick}
|
||||
verifiedMode={verifiedMode}
|
||||
className="upgrade-notification-button"
|
||||
block
|
||||
/>
|
||||
<div className="upgrade-notification-button">
|
||||
<UpgradeButton
|
||||
offer={offer}
|
||||
onClick={logClick}
|
||||
verifiedMode={verifiedMode}
|
||||
block
|
||||
/>
|
||||
</div>
|
||||
{offerCode}
|
||||
</section>
|
||||
);
|
||||
@@ -429,6 +489,7 @@ UpgradeNotification.propTypes = {
|
||||
code: PropTypes.string,
|
||||
}),
|
||||
shouldDisplayBorder: PropTypes.bool,
|
||||
setupgradeNotificationCurrentState: PropTypes.func,
|
||||
timeOffsetMillis: PropTypes.number,
|
||||
upsellPageName: PropTypes.string.isRequired,
|
||||
userTimezone: PropTypes.string,
|
||||
@@ -443,6 +504,7 @@ UpgradeNotification.defaultProps = {
|
||||
accessExpiration: null,
|
||||
contentTypeGatingEnabled: false,
|
||||
offer: null,
|
||||
setupgradeNotificationCurrentState: null,
|
||||
shouldDisplayBorder: null,
|
||||
timeOffsetMillis: 0,
|
||||
userTimezone: null,
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
}
|
||||
|
||||
.upgrade-notification-ul {
|
||||
margin-left: 3rem;
|
||||
padding-left: 1.25rem !important;
|
||||
padding-top: 0.875rem;
|
||||
padding-right: 1.25rem;
|
||||
}
|
||||
@@ -34,9 +34,8 @@
|
||||
}
|
||||
|
||||
.upgrade-notification-button {
|
||||
width: 90%;
|
||||
margin: 0 auto;
|
||||
margin-bottom: 1.25rem;
|
||||
padding: 1.25rem;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.discount-info {
|
||||
|
||||
@@ -50,7 +50,7 @@ describe('Upgrade Notification', () => {
|
||||
it('renders non-FBE when there is a verified mode but no FBE', async () => {
|
||||
buildAndRender();
|
||||
expect(screen.getByRole('heading', { name: 'Pursue a verified certificate' })).toBeInTheDocument();
|
||||
expect(screen.getByText(/Earn a.*?of completion to showcase on your resume/s).textContent).toMatch('Earn a verified certificate of completion to showcase on your resume');
|
||||
expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate of completion to showcase on your resumé');
|
||||
expect(screen.getByText(/Support our.*?at edX/s).textContent).toMatch('Support our non-profit mission at edX');
|
||||
expect(screen.getByRole('link', { name: 'Upgrade for $149' })).toBeInTheDocument();
|
||||
});
|
||||
@@ -64,7 +64,7 @@ describe('Upgrade Notification', () => {
|
||||
},
|
||||
});
|
||||
expect(screen.getByRole('heading', { name: 'Pursue a verified certificate' })).toBeInTheDocument();
|
||||
expect(screen.getByText(/Earn a.*?of completion to showcase on your resume/s).textContent).toMatch('Earn a verified certificate of completion to showcase on your resume');
|
||||
expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate of completion to showcase on your resumé');
|
||||
expect(screen.getByText(/Support our.*?at edX/s).textContent).toMatch('Support our non-profit mission at edX');
|
||||
expect(screen.getByRole('link', { name: 'Upgrade for $149' })).toBeInTheDocument();
|
||||
});
|
||||
@@ -74,7 +74,7 @@ describe('Upgrade Notification', () => {
|
||||
contentTypeGatingEnabled: true,
|
||||
});
|
||||
expect(screen.getByRole('heading', { name: 'Pursue a verified certificate' })).toBeInTheDocument();
|
||||
expect(screen.getByText(/Earn a.*?of completion to showcase on your resume/s).textContent).toMatch('Earn a verified certificate of completion to showcase on your resume');
|
||||
expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate of completion to showcase on your resumé');
|
||||
expect(screen.getByText(/Support our.*?at edX/s).textContent).toMatch('Support our non-profit mission at edX');
|
||||
expect(screen.getByRole('link', { name: 'Upgrade for $149' })).toBeInTheDocument();
|
||||
});
|
||||
@@ -93,7 +93,7 @@ describe('Upgrade Notification', () => {
|
||||
},
|
||||
});
|
||||
expect(screen.getByRole('heading', { name: 'Pursue a verified certificate' })).toBeInTheDocument();
|
||||
expect(screen.getByText(/Earn a.*?of completion to showcase on your resume/s).textContent).toMatch('Earn a verified certificate of completion to showcase on your resume');
|
||||
expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate of completion to showcase on your resumé');
|
||||
expect(screen.getByText(/Support our.*?at edX/s).textContent).toMatch('Support our non-profit mission at edX');
|
||||
expect(screen.getByText(/Upgrade for/).textContent).toMatch('$126.65 ($149)');
|
||||
expect(screen.getByText(/Use code.*?at checkout/s).textContent).toMatch('Use code Welcome15 at checkout');
|
||||
@@ -158,7 +158,7 @@ describe('Upgrade Notification', () => {
|
||||
});
|
||||
expect(screen.getByRole('heading', { name: 'Upgrade your course today' })).toBeInTheDocument();
|
||||
expect(screen.getByText(/Course access will expire/s).textContent).toMatch('Course access will expire April 27');
|
||||
expect(screen.getByText(/Earn a.*?of completion to showcase on your resume/s).textContent).toMatch('Earn a verified certificate of completion to showcase on your resume');
|
||||
expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate of completion to showcase on your resumé');
|
||||
expect(screen.getByText(/Unlock your access/s).textContent).toMatch('Unlock your access to all course activities, including graded assignments');
|
||||
expect(screen.getByText(/to course content and materials/s).textContent).toMatch('Full access to course content and materials, even after the course ends');
|
||||
expect(screen.getByText(/Support our.*?at edX/s).textContent).toMatch('Support our non-profit mission at edX');
|
||||
@@ -186,7 +186,7 @@ describe('Upgrade Notification', () => {
|
||||
});
|
||||
expect(screen.getByRole('heading', { name: '15% First-Time Learner Discount' })).toBeInTheDocument();
|
||||
expect(screen.getByText('Less than 1 hour left')).toBeInTheDocument();
|
||||
expect(screen.getByText(/Earn a.*?of completion to showcase on your resume/s).textContent).toMatch('Earn a verified certificate of completion to showcase on your resume');
|
||||
expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate of completion to showcase on your resumé');
|
||||
expect(screen.getByText(/Unlock your access/s).textContent).toMatch('Unlock your access to all course activities, including graded assignments');
|
||||
expect(screen.getByText(/to course content and materials/s).textContent).toMatch('Full access to course content and materials, even after the course ends');
|
||||
expect(screen.getByText(/Support our.*?at edX/s).textContent).toMatch('Support our non-profit mission at edX');
|
||||
@@ -215,7 +215,7 @@ describe('Upgrade Notification', () => {
|
||||
});
|
||||
expect(screen.getByRole('heading', { name: '15% First-Time Learner Discount' })).toBeInTheDocument();
|
||||
expect(screen.getByText(/hours left/s).textContent).toMatch('12 hours left');
|
||||
expect(screen.getByText(/Earn a.*?of completion to showcase on your resume/s).textContent).toMatch('Earn a verified certificate of completion to showcase on your resume');
|
||||
expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate of completion to showcase on your resumé');
|
||||
expect(screen.getByText(/Unlock your access/s).textContent).toMatch('Unlock your access to all course activities, including graded assignments');
|
||||
expect(screen.getByText(/to course content and materials/s).textContent).toMatch('Full access to course content and materials, even after the course ends');
|
||||
expect(screen.getByText(/Support our.*?at edX/s).textContent).toMatch('Support our non-profit mission at edX');
|
||||
@@ -244,7 +244,7 @@ describe('Upgrade Notification', () => {
|
||||
});
|
||||
expect(screen.getByRole('heading', { name: '15% First-Time Learner Discount' })).toBeInTheDocument();
|
||||
expect(screen.getByText(/days left/s).textContent).toMatch('6 days left');
|
||||
expect(screen.getByText(/Earn a.*?of completion to showcase on your resume/s).textContent).toMatch('Earn a verified certificate of completion to showcase on your resume');
|
||||
expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate of completion to showcase on your resumé');
|
||||
expect(screen.getByText(/Unlock your access/s).textContent).toMatch('Unlock your access to all course activities, including graded assignments');
|
||||
expect(screen.getByText(/to course content and materials/s).textContent).toMatch('Full access to course content and materials, even after the course ends');
|
||||
expect(screen.getByText(/Support our.*?at edX/s).textContent).toMatch('Support our non-profit mission at edX');
|
||||
|
||||
@@ -2,8 +2,12 @@
|
||||
"learning.accessExpiration.deadline": "قم بالترقية قبل {date} للحصول على صلاحية دخول غير محدود طالما أنه موجود على الموقع.",
|
||||
"learning.accessExpiration.header": "تنتهي صلاحية المراجعة في {date}",
|
||||
"learning.accessExpiration.body": "ستفقد كل صلاحيات الدخول إلى هذا المساق، بما في ذلك مسار تقدمك في {date}.",
|
||||
"learning.accessExpiration.expired": "هذا المتعلم ليس لديه حق الوصول إلى هذا المساق، انتهت صلاحية دخوله في{date}.",
|
||||
"instructorToolbar.pageBanner.courseHasExpired": "This learner no longer has access to this course. Their access expired on {date}.",
|
||||
"learning.accessExpiration.upgradeNow": "ترقية الآن",
|
||||
"learning.outline.alert.start.short": "يبدأ المساق في غضون {timeRemaining} في {courseStartDate}.",
|
||||
"learning.outline.alert.end.long": "This course is ending {timeRemaining} on {courseEndDate}.",
|
||||
"learning.outline.alert.end.calendar": "لا تنسى إضافة تذكير في التقويم!",
|
||||
"instructorToolbar.pageBanner.courseHasNotStarted": "This learner does not yet have access to this course. The course starts on {date}.",
|
||||
"learning.enrollment.alert": "يجب أن تكون مسجلا في المساق لمشاهدة المحتوى.",
|
||||
"learning.staff.enrollment.alert": "أنت تستعرض هذا المساق كفرد من فريق طاقم المساق، ولم تلتحق بعد.",
|
||||
"learning.enrollment.enrollNow.Inline": "التحق الآن",
|
||||
@@ -29,15 +33,19 @@
|
||||
"learning.dates.badge.today": "اليوم",
|
||||
"learning.dates.badge.unreleased": "لم يتم الإصدار بعد",
|
||||
"learning.dates.badge.verifiedOnly": "موثق فقط",
|
||||
"learning.goals.unsubscribe.contact": "contact support",
|
||||
"learning.goals.unsubscribe.description": "You will no longer receive email reminders about your goal for {courseTitle}.",
|
||||
"learning.goals.unsubscribe.errorHeader": "Something went wrong",
|
||||
"learning.goals.unsubscribe.goToDashboard": "Go to dashboard",
|
||||
"learning.goals.unsubscribe.header": "You’ve unsubscribed from goal reminders",
|
||||
"learning.goals.unsubscribe.loading": "Unsubscribing…",
|
||||
"learning.goals.unsubscribe.errorDescription": "We were unable to unsubscribe you from goal reminder emails. Please try again later or {contactSupport} for help.",
|
||||
"learning.outline.alert.cert.when": "This course ends on {courseEndDateFormatted}. Final grades and certificates are\n scheduled to be available after {certificateAvailableDate}.",
|
||||
"cert.alert.earned.unavailable.header": "Your grade and certificate will be ready soon!",
|
||||
"cert.alert.earned.ready.header": "Congratulations! Your certificate is ready.",
|
||||
"cert.alert.notPassing.header": "You are not eligible for a certificate",
|
||||
"cert.alert.notPassing.button": "View grades",
|
||||
"learning.outline.alert.end.short": "ينتهي هذا المساق في غضون {timeRemaining}في {courseEndTime}.",
|
||||
"learning.outline.alert.end.long": "يبدأ المساق في {timeRemaining} بتاريخ {courseStartDate}.",
|
||||
"learning.outline.alert.start.short": "يبدأ المساق في غضون {timeRemaining} في {courseStartDate}.",
|
||||
"learning.outline.alert.end.calendar": "لا تنسى إضافة تذكير في التقويم!",
|
||||
"alert.enroll": " to access the full course.",
|
||||
"learning.privateCourse.signInOrRegister": "{signIn} أو {register} ثم التحق بهذا المساق.",
|
||||
"learning.outline.alert.scheduled-content.heading": "More content is coming soon!",
|
||||
@@ -94,9 +102,10 @@
|
||||
"learning.proctoringPanel.onboardingPracticeButton": "View Onboarding Exam",
|
||||
"learning.proctoringPanel.onboardingButtonNotOpen": "Onboarding Opens: {releaseDate}",
|
||||
"learning.proctoringPanel.reviewRequirementsButton": "Review instructions and system requirements",
|
||||
"learning.proctoringPanel.onboardingButtonPastDue": "Onboarding Past Due",
|
||||
"learning.outline.sequence-due": "{description} في{assignmentDue}",
|
||||
"progress.certificateStatus.unverifiedBody": "In order to generate a certificate, you must complete ID verification. {idVerificationSupportLink}.",
|
||||
"progress.certificateStatus.downloadableBody": "Showcase your accomplishment on LinkedIn or your resume today. You can download your certificate now and access it any time from your Dashboard and Profile.",
|
||||
"progress.certificateStatus.downloadableBody": "Showcase your accomplishment on LinkedIn or your resumé today. You can download your certificate now and access it any time from your Dashboard and Profile.",
|
||||
"courseCelebration.certificateBody.notAvailable.endDate": "This course ended on {endDate} and final grades and certificates are scheduled to be\n available after {certAvailableDate}.",
|
||||
"progress.certificateStatus.notPassingHeader": "Certificate status",
|
||||
"progress.certificateStatus.notPassingBody": "In order to qualify for a certificate, you must have a passing grade.",
|
||||
@@ -300,11 +309,15 @@
|
||||
"learn.contentLock.content.locked": "محتوى مغلق",
|
||||
"learn.contentLock.complete.prerequisite": "يجب استيفاء المتطلبات الأساسية: '{priceqSectionName}' للوصول إلى هذا المحتوى.",
|
||||
"learn.contentLock.goToSection": "انتقل إلى قسم المتطلبات الأساسية",
|
||||
"learn.hiddenAfterDue.gradeAvailable": "If you have completed this assignment, your grade is available on the {progressPage}.",
|
||||
"learn.hiddenAfterDue.header": "The due date for this assignment has passed.",
|
||||
"learn.hiddenAfterDue.description": "Because the due date has passed, this assignment is no longer available.",
|
||||
"learn.hiddenAfterDue.progressPage": "progress page",
|
||||
"learn.honorCode.content": "Honesty and academic integrity are important to {siteName} and the institutions providing courses and programs on the {siteName} site. By clicking “I agree” below, I confirm that I have read, understand, and will abide by the {link} for the {siteName} Site.",
|
||||
"learn.honorCode.name": "Honor Code",
|
||||
"learn.honorCode.cancel": "Cancel",
|
||||
"learn.honorCode.agree": "I agree",
|
||||
"gatedContent.paragraph.bulletOne": "Earn a {verifiedCertLink} of completion to showcase on your resume",
|
||||
"gatedContent.paragraph.bulletOne": "Earn a {verifiedCertLink} of completion to showcase on your resumé",
|
||||
"gatedContent.paragraph.bulletTwo": "Unlock access to all course activities, including {gradedAssignments}",
|
||||
"gatedContent.paragraph.bulletThree": "{fullAccess} to course content and materials, even after the course ends",
|
||||
"gatedContent.paragraph.bulletFour": "Support our {nonProfitMission} at edX",
|
||||
@@ -341,7 +354,7 @@
|
||||
"learning.upgradeButton.buttonText": "Upgrade for {pricing}",
|
||||
"learning.upgradeNowButton.buttonText": "Upgrade now for {pricing}",
|
||||
"learning.generic.upgradeNotification.verifiedCertLink": "verified certificate",
|
||||
"learning.generic.upgradeNotification.verifiedCertMessage": "Earn a {verifiedCertLink} of completion to showcase on your resume",
|
||||
"learning.generic.upgradeNotification.verifiedCertMessage": "Earn a {verifiedCertLink} of completion to showcase on your resumé",
|
||||
"learning.generic.upgradeNotification.noFBE.nonProfitMission": "Support our {nonProfitMission} at edX",
|
||||
"learning.generic.upgradeNotification.gradedAssignments": "graded assignments",
|
||||
"learning.generic.upgradeNotification.verifiedCertLink.fullAccess": "Full access",
|
||||
@@ -380,7 +393,7 @@
|
||||
"learning.streakCelebration.streakDiscountMessage": "You’ve unlocked a 15% off discount when you upgrade this course for a limited time only.",
|
||||
"learning.streakcelebration.factoida": "Users who learn {streak_length} days in a row {bolded_section} than those who don’t.",
|
||||
"learning.streakcelebration.factoidb": "Users who learn {streak_length} days in a row {bolded_section} vs. those who don’t.",
|
||||
"learning.streakCelebration.streakAA759EndDateMessage": "Ends {date}.",
|
||||
"learning.streakCelebration.streakCelebrationCouponEndDateMessage": "Ends {date}.",
|
||||
"learning.loading.failure": "حدث خطأ أثناء تحميل هذا المساق.",
|
||||
"learning.loading": "يتم الآن تحميل صفحة المساق..."
|
||||
}
|
||||
@@ -2,17 +2,21 @@
|
||||
"learning.accessExpiration.deadline": "Mejora de categoría antes del {fecha} para obtener acceso ilimitado al curso mientras exista en el sitio.",
|
||||
"learning.accessExpiration.header": "El acceso a tomar el curso de forma gratuita expira el {fecha}",
|
||||
"learning.accessExpiration.body": "Pierdes todo acceso a este curso, incluyendo tu progreso, el {fecha}.",
|
||||
"learning.accessExpiration.expired": "Este estudiante no tiene acceso a este curso. Su acceso expiró el {fecha}.",
|
||||
"instructorToolbar.pageBanner.courseHasExpired": "This learner no longer has access to this course. Their access expired on {date}.",
|
||||
"learning.accessExpiration.upgradeNow": "Actualizar Ahora",
|
||||
"learning.outline.alert.start.short": "El curso comienza en {timeRemaining} a la/s {courseStartTime}.",
|
||||
"learning.outline.alert.end.long": "This course is ending {timeRemaining} on {courseEndDate}.",
|
||||
"learning.outline.alert.end.calendar": "No olvides añadir un recordatorio en el calendario.",
|
||||
"instructorToolbar.pageBanner.courseHasNotStarted": "This learner does not yet have access to this course. The course starts on {date}.",
|
||||
"learning.enrollment.alert": "Debe estar inscrito en el curso para ver el contenido del curso.",
|
||||
"learning.staff.enrollment.alert": "Estás viendo este curso como instructor y no estás inscrito.",
|
||||
"learning.enrollment.enrollNow.Inline": "Inscribirse ahora",
|
||||
"learning.enrollment.enrollNow.Sentence": "Inscríbete ahora.",
|
||||
"learning.enrollment.success": "¡Te has inscrito exitosamente en este curso!",
|
||||
"account-activation.alert.title": "Activate your account so you can log back in",
|
||||
"account-activation.alert.button": "Continue to {siteName}",
|
||||
"account-activation.alert.message": "We sent an email to {boldEmail} with a link to activate your account. Can’t find it? Check your spam folder or\n {sendEmailTag}.",
|
||||
"account-activation.resend.link": "resend the email",
|
||||
"account-activation.alert.title": "Activa tu cuenta para poder volver a conectarte",
|
||||
"account-activation.alert.button": "Continuar a {siteName}",
|
||||
"account-activation.alert.message": "Hemos enviado un email a {boldEmail} con un enlace para activar tu cuenta. ¿No lo encuentras? Verifica tu carpeta de spam o\n {sendEmailTag}.",
|
||||
"account-activation.resend.link": "reenviar el email",
|
||||
"learning.logistration.alert": "Para ver el contenido del curso, {signIn} o {register}.",
|
||||
"learn.navigation.course.tabs.label": "Material del Curso",
|
||||
"header.menu.dashboard.label": "Panel de Control",
|
||||
@@ -29,20 +33,24 @@
|
||||
"learning.dates.badge.today": "Hoy",
|
||||
"learning.dates.badge.unreleased": "Aún no liberado",
|
||||
"learning.dates.badge.verifiedOnly": "Solo verificado",
|
||||
"learning.outline.alert.cert.when": "This course ends on {courseEndDateFormatted}. Final grades and certificates are\n scheduled to be available after {certificateAvailableDate}.",
|
||||
"cert.alert.earned.unavailable.header": "Your grade and certificate will be ready soon!",
|
||||
"cert.alert.earned.ready.header": "Congratulations! Your certificate is ready.",
|
||||
"cert.alert.notPassing.header": "You are not eligible for a certificate",
|
||||
"cert.alert.notPassing.button": "View grades",
|
||||
"learning.goals.unsubscribe.contact": "contacta al equipo de soporte de edX",
|
||||
"learning.goals.unsubscribe.description": "You will no longer receive email reminders about your goal for {courseTitle}.",
|
||||
"learning.goals.unsubscribe.errorHeader": "Something went wrong",
|
||||
"learning.goals.unsubscribe.goToDashboard": "Ir al panel principal",
|
||||
"learning.goals.unsubscribe.header": "You’ve unsubscribed from goal reminders",
|
||||
"learning.goals.unsubscribe.loading": "Unsubscribing…",
|
||||
"learning.goals.unsubscribe.errorDescription": "We were unable to unsubscribe you from goal reminder emails. Please try again later or {contactSupport} for help.",
|
||||
"learning.outline.alert.cert.when": "Este curso finaliza el {courseEndDateFormatted}. Las calificaciones finales y los certificados están\n programados para estar disponibles después de {certificateAvailableDate}.",
|
||||
"cert.alert.earned.unavailable.header": "Tu calificación y tu certificado estarán listos en breve.",
|
||||
"cert.alert.earned.ready.header": "¡Felicitaciones! Tu certificado está listo.",
|
||||
"cert.alert.notPassing.header": "Tú no eres elegible para un certificado",
|
||||
"cert.alert.notPassing.button": "Ver calificaciones",
|
||||
"learning.outline.alert.end.short": "Este curso acaba en {timeRemaining} a la/s {courseEndTime}.",
|
||||
"learning.outline.alert.end.long": "El curso comienza en {timeRemaining} el {courseStartDate}.",
|
||||
"learning.outline.alert.start.short": "El curso comienza en {timeRemaining} a la/s {courseStartTime}.",
|
||||
"learning.outline.alert.end.calendar": "No olvides añadir un recordatorio en el calendario.",
|
||||
"alert.enroll": " to access the full course.",
|
||||
"alert.enroll": " para acceder al curso completo.",
|
||||
"learning.privateCourse.signInOrRegister": "{sign} o {register} y después inscríbete en este curso.",
|
||||
"learning.outline.alert.scheduled-content.heading": "¡Pronto habrá más contenido!",
|
||||
"learning.outline.alert.scheduled-content.body": "This course will have more content released at a future date. Look out for email updates or check back on this course for updates.",
|
||||
"learning.outline.alert.scheduled-content.button": "View Course Schedule",
|
||||
"learning.outline.alert.scheduled-content.body": "Este curso tendrá más contenido en una fecha futura. Presta atención a las actualizaciones por correo electrónico o vuelve a consultar este curso para ver las novedades.",
|
||||
"learning.outline.alert.scheduled-content.button": "Ver el programa del curso",
|
||||
"learning.outline.dates.all": "Ver todas las fechas del curso",
|
||||
"learning.outline.collapseAll": "Colapsar todo",
|
||||
"learning.outline.completedAssignment": "Completado",
|
||||
@@ -81,106 +89,107 @@
|
||||
"learning.proctoringPanel.message.notStarted": "No has comenzado tu examen de integración.",
|
||||
"learning.proctoringPanel.message.started": "Has comenzado tu examen de integración.",
|
||||
"learning.proctoringPanel.message.submitted": "Has enviado tu examen de integración.",
|
||||
"learning.proctoringPanel.message.verified": "Your onboarding exam has been approved in this course.",
|
||||
"learning.proctoringPanel.message.verified": "Tu examen de ingreso ha sido aprobado en este curso.",
|
||||
"learning.proctoringPanel.message.rejected": "Tu examen de integración ha sido rechazado. Vuelve a intentar la integración.",
|
||||
"learning.proctoringPanel.message.error": "Se ha producido un error durante tu examen de integración. Vuelve a intentar la integración.",
|
||||
"learning.proctoringPanel.message.otherCourseApproved": "Your onboarding exam has been approved in another course.",
|
||||
"learning.proctoringPanel.detail.otherCourseApproved": "If your device has changed, we recommend that you complete this course's onboarding exam in order to ensure that your setup still meets the requirements for proctoring.",
|
||||
"learning.proctoringPanel.message.expiringSoon": "Your onboarding profile has been approved in another course. However, your onboarding status is expiring soon. Please complete onboarding again to ensure that you will be able to continue taking proctored exams.",
|
||||
"learning.proctoringPanel.message.otherCourseApproved": "Tu examen de ingreso ha sido aprobado en otro curso.",
|
||||
"learning.proctoringPanel.detail.otherCourseApproved": "Si tu dispositivo ha cambiado, te recomendamos que realices el examen de ingreso de este curso para asegurarte de que tu configuración sigue cumpliendo los requisitos para el examen supervisado.",
|
||||
"learning.proctoringPanel.message.expiringSoon": "Tu perfil de ingreso ha sido aprobado en otro curso. Sin embargo, tu estado de ingreso expirará pronto. Vuelve a completar el proceso de ingreso para asegurarte de que puedas seguir realizando los exámenes supervisados.",
|
||||
"learning.proctoringPanel.generalInfo": "Debes completar el proceso de integración antes de realizar cualquier examen supervisado. ",
|
||||
"learning.proctoringPanel.generalInfoSubmitted": "Tu perfil enviado está en revisión.",
|
||||
"learning.proctoringPanel.generalTime": "Onboarding profile review can take 2+ business days.",
|
||||
"learning.proctoringPanel.generalTime": "La revisión del perfil de ingreso puede tardar más de 2 días laborables.",
|
||||
"learning.proctoringPanel.onboardingButton": "Completar la integración",
|
||||
"learning.proctoringPanel.onboardingPracticeButton": "View Onboarding Exam",
|
||||
"learning.proctoringPanel.onboardingPracticeButton": "Ver el examen de ingreso",
|
||||
"learning.proctoringPanel.onboardingButtonNotOpen": "Apertura de la integración: {releaseDate}",
|
||||
"learning.proctoringPanel.reviewRequirementsButton": "Revisar las instrucciones y los requisitos del sistema",
|
||||
"learning.proctoringPanel.onboardingButtonPastDue": "Onboarding Past Due",
|
||||
"learning.outline.sequence-due": "Fecha límite para {description}: {assignmentDue}",
|
||||
"progress.certificateStatus.unverifiedBody": "In order to generate a certificate, you must complete ID verification. {idVerificationSupportLink}.",
|
||||
"progress.certificateStatus.downloadableBody": "Showcase your accomplishment on LinkedIn or your resume today. You can download your certificate now and access it any time from your Dashboard and Profile.",
|
||||
"courseCelebration.certificateBody.notAvailable.endDate": "This course ended on {endDate} and final grades and certificates are scheduled to be\n available after {certAvailableDate}.",
|
||||
"progress.certificateStatus.notPassingHeader": "Certificate status",
|
||||
"progress.certificateStatus.notPassingBody": "In order to qualify for a certificate, you must have a passing grade.",
|
||||
"progress.certificateStatus.unverifiedBody": "Para generar un certificado, debes completar la verificación de identidad. {idVerificationSupportLink}.",
|
||||
"progress.certificateStatus.downloadableBody": "Showcase your accomplishment on LinkedIn or your resumé today. You can download your certificate now and access it any time from your Dashboard and Profile.",
|
||||
"courseCelebration.certificateBody.notAvailable.endDate": "Este curso terminó el {endDate} y las calificaciones finales y los certificados están programados para estar\ndisponibles después de {certAvailableDate}.",
|
||||
"progress.certificateStatus.notPassingHeader": "Estado del certificado",
|
||||
"progress.certificateStatus.notPassingBody": "Para poder obtener un certificado, es necesario tener una calificación de aprobado.",
|
||||
"progress.certificateStatus.inProgressHeader": "¡Pronto habrá más contenido!",
|
||||
"progress.certificateStatus.inProgressBody": "Parece que hay más contenido en este curso que se publicará en el futuro. Presta atención a las novedades por correo electrónico o consulta tu curso para saber cuándo estará disponible este contenido.",
|
||||
"progress.certificateStatus.requestableHeader": "Certificate status",
|
||||
"progress.certificateStatus.requestableBody": "Congratulations, you qualified for a certificate! In order to access your certificate, request it below.",
|
||||
"progress.certificateStatus.requestableHeader": "Estado del certificado",
|
||||
"progress.certificateStatus.requestableBody": "¡Felicitaciones, has calificado para un certificado! Para acceder a tu certificado, solicítalo a continuación.",
|
||||
"progress.certificateStatus.requestableButton": "Solicitar certificado",
|
||||
"progress.certificateStatus.unverifiedHeader": "Certificate status",
|
||||
"progress.certificateStatus.unverifiedButton": "Verify ID",
|
||||
"progress.certificateStatus.unverifiedHeader": "Estado del certificado",
|
||||
"progress.certificateStatus.unverifiedButton": "Verificar tu identidad",
|
||||
"progress.certificateStatus.courseCelebration.verificationPending": "Su verificación de ID está pendiente y su certificado estará disponible una vez que se haya aprobado.",
|
||||
"progress.certificateStatus.downloadableHeader": "¡Tu certificado está disponible!",
|
||||
"progress.certificateStatus.downloadableButton": "Descargar mi certificado",
|
||||
"progress.certificateStatus.viewableButton": "Ver mi certificado",
|
||||
"progress.certificateStatus.notAvailableHeader": "Certificate status",
|
||||
"progress.certificateStatus.notAvailableHeader": "Estado del certificado",
|
||||
"progress.certificateStatus.upgradeHeader": "Obtén un certificado",
|
||||
"progress.certificateStatus.upgradeBody": "You are in an audit track and do not qualify for a certificate. In order to work towards a certificate, upgrade your course today.",
|
||||
"progress.certificateStatus.upgradeBody": "Estás en la opción auditada y no calificas para un certificado. Para poder obtener un certificado, cambiate a la opción verificada del curso hoy mismo.",
|
||||
"progress.certificateStatus.upgradeButton": "Actualizar Ahora",
|
||||
"progress.certificateStatus.unverifiedHomeHeader": "Verify your identity to earn a certificate!",
|
||||
"progress.certificateStatus.unverifiedHomeButton": "Verify my ID",
|
||||
"progress.certificateStatus.unverifiedHomeBody": "In order to generate a certificate for this course, you must complete the ID verification process.",
|
||||
"progress.certificateStatus.unverifiedHomeHeader": "Verifica tu identidad para obtener un certificado.",
|
||||
"progress.certificateStatus.unverifiedHomeButton": "Verificar mi identidad",
|
||||
"progress.certificateStatus.unverifiedHomeBody": "Para generar un certificado para este curso, debes completar el proceso de verificación de identidad.",
|
||||
"progress.completion.donut.label": "Completado",
|
||||
"progress.completion.body": "This represents how much of the course content you have completed. Note that some content may not yet be released.",
|
||||
"progress.completion.tooltip.locked": "Content that you have completed.",
|
||||
"progress.completion.header": "Course completion",
|
||||
"progress.completion.tooltip": "Content that you have access to and have not completed.",
|
||||
"progress.completion.tooltip.complete": "Content that is locked and available only to those who upgrade.",
|
||||
"progress.completion.donut.percentComplete": "You have completed {percent}% of content in this course.",
|
||||
"progress.completion.donut.percentIncomplete": "You have not completed {percent}% of content in this course that you have access to.",
|
||||
"progress.completion.donut.percentLocked": "{percent}% of content in this course is locked and available only for those who upgrade.",
|
||||
"progress.ungradedAlert": "For progress on ungraded aspects of the course, view your {outlineLink}.",
|
||||
"progress.completion.body": "Esto representa la cantidad de contenido del curso que has completado. Debes de tener en cuenta que es posible que algunos contenidos aún no se hayan publicado.",
|
||||
"progress.completion.tooltip.locked": "Contenido que has completado.",
|
||||
"progress.completion.header": "Finalización del curso",
|
||||
"progress.completion.tooltip": "Contenido al que tienes acceso y que no has completado.",
|
||||
"progress.completion.tooltip.complete": "Contenido bloqueado y disponible sólo para quienes se cambien a la opción verificada.",
|
||||
"progress.completion.donut.percentComplete": "Has completado {percent}% del contenido en este curso.",
|
||||
"progress.completion.donut.percentIncomplete": "No has completado el {percent}% del contenido en este curso al que tienes acceso.",
|
||||
"progress.completion.donut.percentLocked": "El {percent}% del contenido de este curso que está bloqueado y disponible sólo para aquellos que se cambien a la opción verificada.",
|
||||
"progress.ungradedAlert": "Para el progreso en los aspectos no calificados del curso, visita tu {outlineLink}.",
|
||||
"progress.footnotes.droppableAssignments": "The lowest {numDroppable, plural, one{# {assignmentType} score is} other{# {assignmentType} scores are}} dropped.",
|
||||
"progress.assignmentType": "Assignment type",
|
||||
"progress.footnotes.backToContent": "Back to content",
|
||||
"progress.courseGrade.body": "This represents your weighted grade against the grade needed to pass this course.",
|
||||
"progress.courseGrade.gradeBar.altText": "Your current grade is {currentGrade}%. A weighted grade of {passingGrade}% is required to pass in this course.",
|
||||
"progress.courseGrade.footer.generic.passing": "You’re currently passing this course",
|
||||
"progress.courseGrade.footer.nonPassing": "A weighted grade of {passingGrade}% is required to pass in this course",
|
||||
"progress.courseGrade.footer.passing": "You’re currently passing this course with a grade of {letterGrade} ({minGrade}-{maxGrade}%)",
|
||||
"progress.courseGrade.preview.headerLocked": "locked feature",
|
||||
"progress.courseGrade.preview.headerLimited": "limited feature",
|
||||
"progress.courseGrade.preview.header.ariaHidden": "Preview of a ",
|
||||
"progress.courseGrade.preview.body.unlockCertificate": "Unlock to view grades and work towards a certificate.",
|
||||
"progress.courseGrade.partialpreview.body.unlockCertificate": "Unlock to work towards a certificate.",
|
||||
"progress.courseGrade.preview.body.upgradeDeadlinePassed": "The deadline to upgrade in this course has passed.",
|
||||
"progress.assignmentType": "Tipo de tarea",
|
||||
"progress.footnotes.backToContent": "Regresar al contenido",
|
||||
"progress.courseGrade.body": "Esto representa tu calificación ponderada con respecto a la calificación necesaria para aprobar este curso.",
|
||||
"progress.courseGrade.gradeBar.altText": "Tu calificación actual es {currentGrade}%. Se requiere una calificación promedio de {passingGrade}% para aprobar este curso.",
|
||||
"progress.courseGrade.footer.generic.passing": "Actualmente estás aprobando este curso",
|
||||
"progress.courseGrade.footer.nonPassing": "Para aprobar ese curso es necesario obtener una nota promedio de {passingGrade}%.",
|
||||
"progress.courseGrade.footer.passing": "Actualmente estás aprobando este curso con una calificación de {letterGrade} ({minGrade}-{maxGrade}%)",
|
||||
"progress.courseGrade.preview.headerLocked": "función bloqueada",
|
||||
"progress.courseGrade.preview.headerLimited": "función limitada",
|
||||
"progress.courseGrade.preview.header.ariaHidden": "Vista preliminar de un",
|
||||
"progress.courseGrade.preview.body.unlockCertificate": "Desbloquear para ver las calificaciones y trabajar para obtener un certificado.",
|
||||
"progress.courseGrade.partialpreview.body.unlockCertificate": "Desbloquear para trabajar en la obtención de un certificado.",
|
||||
"progress.courseGrade.preview.body.upgradeDeadlinePassed": "El plazo para cambiar a la opción verificada en este curso ha pasado.",
|
||||
"progress.courseGrade.preview.button.upgrade": "Actualizar Ahora",
|
||||
"progress.courseGrade.gradeRange.tooltip": "Grade ranges for this course:",
|
||||
"progress.courseGrade.gradeRange.tooltip": "Rangos de calificaciones para este curso:",
|
||||
"progress.courseOutline": "Estructura del curso",
|
||||
"progress.courseGrade.label.currentGrade": "Your current grade",
|
||||
"progress.detailedGrades": "Detailed grades",
|
||||
"progress.detailedGrades.emptyTable": "You currently have no graded problem scores.",
|
||||
"progress.footnotes.title": "Grade summary footnotes",
|
||||
"progress.courseGrade.label.currentGrade": "Tu calificación actual",
|
||||
"progress.detailedGrades": "Calificaciones detalladas",
|
||||
"progress.detailedGrades.emptyTable": "Actualmente no tiene puntajes de problemas calificados.",
|
||||
"progress.footnotes.title": "Nota al pie del resumen de la calificación ",
|
||||
"progress.gradeSummary.grade": "Calificación",
|
||||
"progress.courseGrade.grades": "Grades",
|
||||
"progress.courseGrade.gradeRange.Tooltip": "Grade range tooltip",
|
||||
"progress.courseGrade.grades": "Calificaciones",
|
||||
"progress.courseGrade.gradeRange.Tooltip": "Información sobre el rango de notas",
|
||||
"progress.gradeSummary": "Resumen de calificaciones",
|
||||
"progress.gradeSummary.limitedAccessExplanation": "You have limited access to graded assignments as part of the audit track in this course.",
|
||||
"progress.gradeSummary.tooltip.alt": "Grade summary tooltip",
|
||||
"progress.gradeSummary.tooltip.body": "Your course assignment's weight is determined by your instructor. By multiplying your grade by the weight for that assignment type, your weighted grade is calculated. Your weighted grade is what's used to determine if you pass the course.",
|
||||
"progress.courseGrade.label.passingGrade": "Passing grade",
|
||||
"progress.detailedGrades.problemScore.label": "Problem Scores:",
|
||||
"progress.detailedGrades.problemScore.toggleButton": "Toggle individual problem scores for {subsectionTitle}",
|
||||
"progress.gradeSummary.limitedAccessExplanation": "Tienes acceso limitado a las tareas calificadas como parte de la opción auditada en este curso.",
|
||||
"progress.gradeSummary.tooltip.alt": "Información sobre el resumen de la nota",
|
||||
"progress.gradeSummary.tooltip.body": "La ponderación de la tarea del curso la determina el profesor. Tu calificación ponderada se calcula multiplicando tu calificación por el peso de ese tipo de tarea. Tu calificación ponderada es la que se utiliza para determinar si apruebas el curso.",
|
||||
"progress.courseGrade.label.passingGrade": "Calificación de aprobado",
|
||||
"progress.detailedGrades.problemScore.label": "Puntajes de problemas:",
|
||||
"progress.detailedGrades.problemScore.toggleButton": "Cambiar puntajes del problema individual por {subsectionTitle}",
|
||||
"progress.score": "Puntaje",
|
||||
"progress.weight": "Peso",
|
||||
"progress.weightedGrade": "Weighted grade",
|
||||
"progress.weightedGradeSummary": "Your current weighted grade summary",
|
||||
"progress.noAcessToAssignmentType": "You do not have access to assignments of type {assignmentType}",
|
||||
"progress.noAcessToSubsection": "You do not have access to subsection {displayName}",
|
||||
"progress.header": "Your progress",
|
||||
"progress.header.targetUser": "Course progress for {username}",
|
||||
"progress.weightedGrade": "Calificación promedio",
|
||||
"progress.weightedGradeSummary": "Tu resumen de calificación ponderada actual",
|
||||
"progress.noAcessToAssignmentType": "No tienes acceso a las tareas de tipo {assignmentType}",
|
||||
"progress.noAcessToSubsection": "No tienes acceso a la subsección {displayName}",
|
||||
"progress.header": "Tu progreso",
|
||||
"progress.header.targetUser": "Progreso del curso para {nombre de usuario}",
|
||||
"progress.link.studio": "Ver las calificaciones en Studio",
|
||||
"progress.relatedLinks.datesCard.description": "A schedule view of your course due dates and upcoming assignments.",
|
||||
"progress.relatedLinks.datesCard.description": "Un calendario con los plazos del curso y las fechas de las próximas tareas.",
|
||||
"progress.relatedLinks.datesCard.link": "Fechas",
|
||||
"progress.relatedLinks.outlineCard.description": "A birds-eye view of your course content.",
|
||||
"progress.relatedLinks.outlineCard.description": "Una vista a grandes rasgos del contenido del curso .",
|
||||
"progress.relatedLinks.outlineCard.link": "Estructura del curso",
|
||||
"progress.relatedLinks": "Related links",
|
||||
"datesBanner.suggestedSchedule": "We’ve built a suggested schedule to help you stay on track. But don’t worry—it’s flexible so you can learn at your own pace.",
|
||||
"progress.relatedLinks": "Enlaces relacionados",
|
||||
"datesBanner.suggestedSchedule": "Hemos creado un calendario sugerido para ayudarte a alcanzar tus metas. Pero no te preocupes, es flexible para que puedas aprender a tu propio ritmo.",
|
||||
"datesBanner.upgradeToCompleteGradedBanner.header": "Opta por el certificado para desbloquear",
|
||||
"datesBanner.upgradeToCompleteGradedBanner.body": "You are auditing this course, which means that you are unable to participate in graded assignments. To complete graded assignments as part of this course, you can upgrade today.",
|
||||
"datesBanner.upgradeToCompleteGradedBanner.body": "Estás auditando este curso, lo que significa que no puedes participar en las tareas calificadas. Para completar las tareas calificadas como parte de este curso, puedes cambiarte a la opción con certificado.",
|
||||
"datesBanner.upgradeToCompleteGradedBanner.button": "Actualizar Ahora",
|
||||
"datesBanner.upgradeToResetBanner.body": "To keep yourself on track, you can update this schedule and shift the past due assignments into the future. Don’t worry—you won’t lose any of the progress you’ve made when you shift your due dates.",
|
||||
"datesBanner.upgradeToResetBanner.body": "Para mantener el ritmo y alcanzar tus metas, puedes actualizar este calendario y mover las tareas vencidas hacia el futuro. No te preocupes, no perderás nada de lo que ya has avanzado cuando cambies las fechas de entrega.",
|
||||
"datesBanner.upgradeToResetBanner.button": "Actualizar para cambiar las fechas de vencimiento",
|
||||
"datesBanner.resetDatesBanner.header": "Parece que no cumplió algunos plazos importantes según nuestro calendario sugerido.",
|
||||
"datesBanner.resetDatesBanner.body": "To keep yourself on track, you can update this schedule and shift the past due assignments into the future. Don’t worry—you won’t lose any of the progress you’ve made when you shift your due dates.",
|
||||
"datesBanner.resetDatesBanner.body": "Para mantener el ritmo y alcanzar tus metas, puedes actualizar este calendario y mover las tareas vencidas hacia el futuro. No te preocupes, no perderás nada de lo que ya has avanzado cuando cambies las fechas de entrega.",
|
||||
"datesBanner.resetDatesBanner.button": "Cambiar fechas de vencimiento",
|
||||
"unit.bookmark.button.add.bookmark": "Marcar esta página",
|
||||
"unit.bookmark.button.remove.bookmark": "Página marcada",
|
||||
@@ -241,13 +250,13 @@
|
||||
"courseCelebration.dashboardInfo": "Puedes acceder a este curso y a sus materiales en tu {dashboardLink}.",
|
||||
"courseExit.programs.applyForCredit": "Solicitar crédito",
|
||||
"courseCelebration.certificateHeader.downloadable": "¡Tu certificado está disponible!",
|
||||
"courseCelebration.certificateHeader.notAvailable": "Your grade and certificate will be ready soon!",
|
||||
"courseCelebration.certificateBody.notAvailable.accessCertificate": "If you have earned a passing grade, your certificate will be automatically issued.",
|
||||
"courseCelebration.certificateHeader.notAvailable": "Tu calificación y tu certificado estarán listos en breve.",
|
||||
"courseCelebration.certificateBody.notAvailable.accessCertificate": "Si has obtenido una calificación de aprobado, tu certificado se emitirá automáticamente.",
|
||||
"courseCelebration.certificateHeader.unverified": "Debes completar la verificación para recibir tu certificado.",
|
||||
"courseCelebration.certificateHeader.requestable": "¡Felicitaciones, usted califica para recibir un certificado!",
|
||||
"courseCelebration.certificateHeader.upgradable": "Mejora de categoría para obtener un certificado verificado",
|
||||
"courseCelebration.certificateImage": "Modelo de certificado",
|
||||
"courseCelebration.completedCourseHeader": "You have completed your course.",
|
||||
"courseCelebration.completedCourseHeader": "Has completado el curso.",
|
||||
"courseCelebration.congratulationsHeader": "¡Felicitaciones!",
|
||||
"courseCelebration.congratulationsImage": "Cuatro personas levantando las manos en señal de celebración",
|
||||
"courseExit.courseInProgressDescription": "Parece que hay más contenido en este curso que se publicará en el futuro. Presta atención a las novedades por correo electrónico o consulta tu curso para saber cuándo estará disponible este contenido.",
|
||||
@@ -269,7 +278,7 @@
|
||||
"courseCelebration.requestCertificateBodyText": "Para acceder a tu certificado, solicítalo a continuación.",
|
||||
"courseCelebration.requestCertificateButton": "Solicitar certificado",
|
||||
"courseExit.searchOurCatalogLink": "Buscar en nuestro catálogo",
|
||||
"courseCelebration.shareMessage": "Share your success on social media or email.",
|
||||
"courseCelebration.shareMessage": "Comparte tu éxito en redes sociales o por correo electrónico.",
|
||||
"courseExit.social.shareCompletionMessage": "¡Acabo de completar {title} con {plataform}!",
|
||||
"courseExit.upgradeButton": "Actualizar Ahora",
|
||||
"courseExit.upgradeLink": "mejora de categoría ahora",
|
||||
@@ -293,17 +302,21 @@
|
||||
"learn.breadcrumb.navigation.course.home": "Curso",
|
||||
"notification.tray.container": "Notificación de la barra lateral",
|
||||
"notification.open.button": "Mostrar la notificación de la barra lateral",
|
||||
"notification.close.button": "Close notification tray",
|
||||
"notification.close.button": "Cerrar la bandeja de notificaciones",
|
||||
"responsive.close.notification": "Regresar al curso",
|
||||
"notification.tray.title": "Notificaciones",
|
||||
"notification.tray.no.message": "No tienes notificaciones nuevas en este momento.",
|
||||
"learn.contentLock.content.locked": "Contenido Bloqueado",
|
||||
"learn.contentLock.complete.prerequisite": "Debe completar el prerrequisito: '{prereqSectionName}'para acceder a este contenido.",
|
||||
"learn.contentLock.goToSection": "Ir a la Sección de Prerrequisitos",
|
||||
"learn.honorCode.content": "Honesty and academic integrity are important to {siteName} and the institutions providing courses and programs on the {siteName} site. By clicking “I agree” below, I confirm that I have read, understand, and will abide by the {link} for the {siteName} Site.",
|
||||
"learn.hiddenAfterDue.gradeAvailable": "If you have completed this assignment, your grade is available on the {progressPage}.",
|
||||
"learn.hiddenAfterDue.header": "The due date for this assignment has passed.",
|
||||
"learn.hiddenAfterDue.description": "Because the due date has passed, this assignment is no longer available.",
|
||||
"learn.hiddenAfterDue.progressPage": "progress page",
|
||||
"learn.honorCode.content": "La honestidad y la integridad académica son importantes para {siteName} y las instituciones que ofrecen cursos y programas en el sitio {siteName}. Al hacer clic en \"Estoy de acuerdo\" a continuación, confirmo que he leído, entiendo y cumpliré con el {link} del sitio {siteName}.",
|
||||
"learn.honorCode.name": "Código de Honor",
|
||||
"learn.honorCode.cancel": "Cancelar",
|
||||
"learn.honorCode.agree": "I agree",
|
||||
"learn.honorCode.agree": "Estoy de acuerdo ",
|
||||
"gatedContent.paragraph.bulletOne": "Obtén un {verifiedCertLink} de finalización para compartirlo en tu currículum",
|
||||
"gatedContent.paragraph.bulletTwo": "Desbloquea el acceso a todas las actividades del curso, incluidas las {gradedAssignments}",
|
||||
"gatedContent.paragraph.bulletThree": "{fullAccess} al contenido y los materiales del curso, incluso después de que finalice el curso",
|
||||
@@ -317,12 +330,12 @@
|
||||
"learn.lockPaywall.list.bullet3.boldtext": "Acceso completo",
|
||||
"learn.lockPaywall.list.bullet4.boldtext": "misión sin fines de lucro",
|
||||
"learn.loading.content.lock": "Cargando la mensajería de contenido bloqueado...",
|
||||
"learn.loading.honor.codk": "Loading honor code messaging...",
|
||||
"learn.loading.honor.codk": "Cargando el mensaje de código de honor...",
|
||||
"learn.loading.learning.sequence": "Cargando la secuencia de aprendizaje...",
|
||||
"learn.course.load.failure": "Hubo un error al cargar este curso.",
|
||||
"learn.sequence.no.content": "Aquí no hay contenido.",
|
||||
"learn.sequence.navigation.next.button": "Siguiente",
|
||||
"learn.sequence.navigation.next.up.button": "Next Up: {title}",
|
||||
"learn.sequence.navigation.next.up.button": "Siguiente: {title}",
|
||||
"learn.sequence.navigation.previous.button": "Anterior",
|
||||
"learn.course.sequence.navigation.mobile.menu": "{current} de {total}",
|
||||
"learn.redirect.interstitial.message": "Redirigiendo...",
|
||||
@@ -338,7 +351,7 @@
|
||||
"learn.course.tabs.navigation.overflow.menu": "Más...",
|
||||
"learning.offer.screenReaderPrices": "Precio original: {originalPrice}; precio con descuento: {discountedPrice}",
|
||||
"learning.upgradeButton.screenReaderInlinePrices": "Precio original: {originalPrice}",
|
||||
"learning.upgradeButton.buttonText": "Upgrade for {pricing}",
|
||||
"learning.upgradeButton.buttonText": "Opción verificada {pricing}",
|
||||
"learning.upgradeNowButton.buttonText": "Cambia a la opción paga por {pricing}",
|
||||
"learning.generic.upgradeNotification.verifiedCertLink": "certificado verificado",
|
||||
"learning.generic.upgradeNotification.verifiedCertMessage": "Obtén un {verifiedCertLink} de finalización para compartirlo en tu currículum",
|
||||
@@ -366,21 +379,21 @@
|
||||
"masquerade-widget.userName.input.placeholder": "Nombre de usuario o correo electrónico",
|
||||
"masquerade-widget.userName.input.label": "Hazte pasar por este usuario",
|
||||
"learning.effortEstimation.combinedEstimate": "{minutes} + {activities}",
|
||||
"learning.effortEstimation.activities": "{activityCount, plural, one {# activity} other {# activities}}",
|
||||
"learning.effortEstimation.minutesAbbreviated": "{minuteCount, plural, one {# min} other {# min}}",
|
||||
"learning.effortEstimation.minutesFull": "{minuteCount, plural, one {# minute} other {# minutes}}",
|
||||
"learning.effortEstimation.activities": "{activityCount, plural, one {# de actividades} other {# actividades}}",
|
||||
"learning.effortEstimation.minutesAbbreviated": "{minuteCount, plural, one {# minutos} other {# min}}",
|
||||
"learning.effortEstimation.minutesFull": "{minuteCount, plural, one {# minutos} other {# minutos}}",
|
||||
"learning.streakCelebration.congratulations": "¡Felicitaciones!",
|
||||
"learning.streakCelebration.body": "Sigue así, ¡estás de buena racha!",
|
||||
"learning.streakCelebration.button": "Sigue así",
|
||||
"learning.streakCelebration.buttonSrOnly": "Cerrar el modal y continuar",
|
||||
"learning.streakCelebration.buttonAA759": "Continuar con el curso",
|
||||
"learning.streakCelebration.header": "day streak",
|
||||
"learning.streakCelebration.header": "días de racha",
|
||||
"learning.streakCelebration.factoidABoldedSection": "tienen 20 veces más probabilidades de aprobar el curso",
|
||||
"learning.streakCelebration.factoidBBoldedSection": "completan 5 veces la cantidad de contenido del curso en promedio",
|
||||
"learning.streakCelebration.streakDiscountMessage": "Has desbloqueado un descuento del 15% al cambiar a la opción page de este curso sólo por tiempo limitado.",
|
||||
"learning.streakcelebration.factoida": "Los usuarios que aprenden {streak_length} días seguidos {bolded_section} que los que no lo hacen.",
|
||||
"learning.streakcelebration.factoidb": "Los usuarios que aprenden {streak_length} días seguidos {bolded_section} frente a los que no lo hacen.",
|
||||
"learning.streakCelebration.streakAA759EndDateMessage": "Termina {date}.",
|
||||
"learning.streakCelebration.streakCelebrationCouponEndDateMessage": "Ends {date}.",
|
||||
"learning.loading.failure": "Hubo un error al cargar este curso.",
|
||||
"learning.loading": "Cargando la página del curso..."
|
||||
}
|
||||
@@ -2,8 +2,12 @@
|
||||
"learning.accessExpiration.deadline": "Upgrade by {date} to get unlimited access to the course as long as it exists on the site.",
|
||||
"learning.accessExpiration.header": "Audit Access Expires {date}",
|
||||
"learning.accessExpiration.body": "You lose all access to this course, including your progress, on {date}.",
|
||||
"learning.accessExpiration.expired": "This learner does not have access to this course. Their access expired on {date}.",
|
||||
"instructorToolbar.pageBanner.courseHasExpired": "This learner no longer has access to this course. Their access expired on {date}.",
|
||||
"learning.accessExpiration.upgradeNow": "Upgrade now",
|
||||
"learning.outline.alert.start.short": "Course starts {timeRemaining} at {courseStartTime}.",
|
||||
"learning.outline.alert.end.long": "This course is ending {timeRemaining} on {courseEndDate}.",
|
||||
"learning.outline.alert.end.calendar": "Don’t forget to add a calendar reminder!",
|
||||
"instructorToolbar.pageBanner.courseHasNotStarted": "This learner does not yet have access to this course. The course starts on {date}.",
|
||||
"learning.enrollment.alert": "You must be enrolled in the course to see course content.",
|
||||
"learning.staff.enrollment.alert": "You are viewing this course as staff, and are not enrolled.",
|
||||
"learning.enrollment.enrollNow.Inline": "Enroll now",
|
||||
@@ -29,15 +33,19 @@
|
||||
"learning.dates.badge.today": "Today",
|
||||
"learning.dates.badge.unreleased": "Not yet released",
|
||||
"learning.dates.badge.verifiedOnly": "Verified only",
|
||||
"learning.goals.unsubscribe.contact": "contact support",
|
||||
"learning.goals.unsubscribe.description": "You will no longer receive email reminders about your goal for {courseTitle}.",
|
||||
"learning.goals.unsubscribe.errorHeader": "Something went wrong",
|
||||
"learning.goals.unsubscribe.goToDashboard": "Go to dashboard",
|
||||
"learning.goals.unsubscribe.header": "You’ve unsubscribed from goal reminders",
|
||||
"learning.goals.unsubscribe.loading": "Unsubscribing…",
|
||||
"learning.goals.unsubscribe.errorDescription": "We were unable to unsubscribe you from goal reminder emails. Please try again later or {contactSupport} for help.",
|
||||
"learning.outline.alert.cert.when": "This course ends on {courseEndDateFormatted}. Final grades and certificates are\n scheduled to be available after {certificateAvailableDate}.",
|
||||
"cert.alert.earned.unavailable.header": "Your grade and certificate will be ready soon!",
|
||||
"cert.alert.earned.ready.header": "Congratulations! Your certificate is ready.",
|
||||
"cert.alert.notPassing.header": "You are not eligible for a certificate",
|
||||
"cert.alert.notPassing.button": "View grades",
|
||||
"learning.outline.alert.end.short": "This course is ending {timeRemaining} at {courseEndTime}.",
|
||||
"learning.outline.alert.end.long": "Course starts {timeRemaining} on {courseStartDate}.",
|
||||
"learning.outline.alert.start.short": "Course starts {timeRemaining} at {courseStartTime}.",
|
||||
"learning.outline.alert.end.calendar": "Don’t forget to add a calendar reminder!",
|
||||
"alert.enroll": " to access the full course.",
|
||||
"learning.privateCourse.signInOrRegister": "{signIn} or {register} and then enroll in this course.",
|
||||
"learning.outline.alert.scheduled-content.heading": "More content is coming soon!",
|
||||
@@ -94,9 +102,10 @@
|
||||
"learning.proctoringPanel.onboardingPracticeButton": "View Onboarding Exam",
|
||||
"learning.proctoringPanel.onboardingButtonNotOpen": "Onboarding Opens: {releaseDate}",
|
||||
"learning.proctoringPanel.reviewRequirementsButton": "Review instructions and system requirements",
|
||||
"learning.proctoringPanel.onboardingButtonPastDue": "Onboarding Past Due",
|
||||
"learning.outline.sequence-due": "{description} due {assignmentDue}",
|
||||
"progress.certificateStatus.unverifiedBody": "In order to generate a certificate, you must complete ID verification. {idVerificationSupportLink}.",
|
||||
"progress.certificateStatus.downloadableBody": "Showcase your accomplishment on LinkedIn or your resume today. You can download your certificate now and access it any time from your Dashboard and Profile.",
|
||||
"progress.certificateStatus.downloadableBody": "Showcase your accomplishment on LinkedIn or your resumé today. You can download your certificate now and access it any time from your Dashboard and Profile.",
|
||||
"courseCelebration.certificateBody.notAvailable.endDate": "This course ended on {endDate} and final grades and certificates are scheduled to be\n available after {certAvailableDate}.",
|
||||
"progress.certificateStatus.notPassingHeader": "Certificate status",
|
||||
"progress.certificateStatus.notPassingBody": "In order to qualify for a certificate, you must have a passing grade.",
|
||||
@@ -300,11 +309,15 @@
|
||||
"learn.contentLock.content.locked": "Content Locked",
|
||||
"learn.contentLock.complete.prerequisite": "You must complete the prerequisite: '{prereqSectionName}' to access this content.",
|
||||
"learn.contentLock.goToSection": "Go To Prerequisite Section",
|
||||
"learn.hiddenAfterDue.gradeAvailable": "If you have completed this assignment, your grade is available on the {progressPage}.",
|
||||
"learn.hiddenAfterDue.header": "The due date for this assignment has passed.",
|
||||
"learn.hiddenAfterDue.description": "Because the due date has passed, this assignment is no longer available.",
|
||||
"learn.hiddenAfterDue.progressPage": "progress page",
|
||||
"learn.honorCode.content": "Honesty and academic integrity are important to {siteName} and the institutions providing courses and programs on the {siteName} site. By clicking “I agree” below, I confirm that I have read, understand, and will abide by the {link} for the {siteName} Site.",
|
||||
"learn.honorCode.name": "Honor Code",
|
||||
"learn.honorCode.cancel": "Cancel",
|
||||
"learn.honorCode.agree": "I agree",
|
||||
"gatedContent.paragraph.bulletOne": "Earn a {verifiedCertLink} of completion to showcase on your resume",
|
||||
"gatedContent.paragraph.bulletOne": "Earn a {verifiedCertLink} of completion to showcase on your resumé",
|
||||
"gatedContent.paragraph.bulletTwo": "Unlock access to all course activities, including {gradedAssignments}",
|
||||
"gatedContent.paragraph.bulletThree": "{fullAccess} to course content and materials, even after the course ends",
|
||||
"gatedContent.paragraph.bulletFour": "Support our {nonProfitMission} at edX",
|
||||
@@ -341,7 +354,7 @@
|
||||
"learning.upgradeButton.buttonText": "Upgrade for {pricing}",
|
||||
"learning.upgradeNowButton.buttonText": "Upgrade now for {pricing}",
|
||||
"learning.generic.upgradeNotification.verifiedCertLink": "verified certificate",
|
||||
"learning.generic.upgradeNotification.verifiedCertMessage": "Earn a {verifiedCertLink} of completion to showcase on your resume",
|
||||
"learning.generic.upgradeNotification.verifiedCertMessage": "Earn a {verifiedCertLink} of completion to showcase on your resumé",
|
||||
"learning.generic.upgradeNotification.noFBE.nonProfitMission": "Support our {nonProfitMission} at edX",
|
||||
"learning.generic.upgradeNotification.gradedAssignments": "graded assignments",
|
||||
"learning.generic.upgradeNotification.verifiedCertLink.fullAccess": "Full access",
|
||||
@@ -380,7 +393,7 @@
|
||||
"learning.streakCelebration.streakDiscountMessage": "You’ve unlocked a 15% off discount when you upgrade this course for a limited time only.",
|
||||
"learning.streakcelebration.factoida": "Users who learn {streak_length} days in a row {bolded_section} than those who don’t.",
|
||||
"learning.streakcelebration.factoidb": "Users who learn {streak_length} days in a row {bolded_section} vs. those who don’t.",
|
||||
"learning.streakCelebration.streakAA759EndDateMessage": "Ends {date}.",
|
||||
"learning.streakCelebration.streakCelebrationCouponEndDateMessage": "Ends {date}.",
|
||||
"learning.loading.failure": "There was an error loading this course.",
|
||||
"learning.loading": "Loading course page…"
|
||||
}
|
||||
@@ -2,8 +2,12 @@
|
||||
"learning.accessExpiration.deadline": "Upgrade by {date} to get unlimited access to the course as long as it exists on the site.",
|
||||
"learning.accessExpiration.header": "Audit Access Expires {date}",
|
||||
"learning.accessExpiration.body": "You lose all access to this course, including your progress, on {date}.",
|
||||
"learning.accessExpiration.expired": "This learner does not have access to this course. Their access expired on {date}.",
|
||||
"instructorToolbar.pageBanner.courseHasExpired": "This learner no longer has access to this course. Their access expired on {date}.",
|
||||
"learning.accessExpiration.upgradeNow": "Upgrade now",
|
||||
"learning.outline.alert.start.short": "Course starts {timeRemaining} at {courseStartTime}.",
|
||||
"learning.outline.alert.end.long": "This course is ending {timeRemaining} on {courseEndDate}.",
|
||||
"learning.outline.alert.end.calendar": "Don’t forget to add a calendar reminder!",
|
||||
"instructorToolbar.pageBanner.courseHasNotStarted": "This learner does not yet have access to this course. The course starts on {date}.",
|
||||
"learning.enrollment.alert": "You must be enrolled in the course to see course content.",
|
||||
"learning.staff.enrollment.alert": "You are viewing this course as staff, and are not enrolled.",
|
||||
"learning.enrollment.enrollNow.Inline": "Enroll now",
|
||||
@@ -29,15 +33,19 @@
|
||||
"learning.dates.badge.today": "Today",
|
||||
"learning.dates.badge.unreleased": "Not yet released",
|
||||
"learning.dates.badge.verifiedOnly": "Verified only",
|
||||
"learning.goals.unsubscribe.contact": "contact support",
|
||||
"learning.goals.unsubscribe.description": "You will no longer receive email reminders about your goal for {courseTitle}.",
|
||||
"learning.goals.unsubscribe.errorHeader": "Something went wrong",
|
||||
"learning.goals.unsubscribe.goToDashboard": "Go to dashboard",
|
||||
"learning.goals.unsubscribe.header": "You’ve unsubscribed from goal reminders",
|
||||
"learning.goals.unsubscribe.loading": "Unsubscribing…",
|
||||
"learning.goals.unsubscribe.errorDescription": "We were unable to unsubscribe you from goal reminder emails. Please try again later or {contactSupport} for help.",
|
||||
"learning.outline.alert.cert.when": "This course ends on {courseEndDateFormatted}. Final grades and certificates are\n scheduled to be available after {certificateAvailableDate}.",
|
||||
"cert.alert.earned.unavailable.header": "Your grade and certificate will be ready soon!",
|
||||
"cert.alert.earned.ready.header": "Congratulations! Your certificate is ready.",
|
||||
"cert.alert.notPassing.header": "You are not eligible for a certificate",
|
||||
"cert.alert.notPassing.button": "View grades",
|
||||
"learning.outline.alert.end.short": "This course is ending {timeRemaining} at {courseEndTime}.",
|
||||
"learning.outline.alert.end.long": "Course starts {timeRemaining} on {courseStartDate}.",
|
||||
"learning.outline.alert.start.short": "Course starts {timeRemaining} at {courseStartTime}.",
|
||||
"learning.outline.alert.end.calendar": "Don’t forget to add a calendar reminder!",
|
||||
"alert.enroll": " to access the full course.",
|
||||
"learning.privateCourse.signInOrRegister": "{signIn} or {register} and then enroll in this course.",
|
||||
"learning.outline.alert.scheduled-content.heading": "More content is coming soon!",
|
||||
@@ -94,9 +102,10 @@
|
||||
"learning.proctoringPanel.onboardingPracticeButton": "View Onboarding Exam",
|
||||
"learning.proctoringPanel.onboardingButtonNotOpen": "Onboarding Opens: {releaseDate}",
|
||||
"learning.proctoringPanel.reviewRequirementsButton": "Review instructions and system requirements",
|
||||
"learning.proctoringPanel.onboardingButtonPastDue": "Onboarding Past Due",
|
||||
"learning.outline.sequence-due": "{description} due {assignmentDue}",
|
||||
"progress.certificateStatus.unverifiedBody": "In order to generate a certificate, you must complete ID verification. {idVerificationSupportLink}.",
|
||||
"progress.certificateStatus.downloadableBody": "Showcase your accomplishment on LinkedIn or your resume today. You can download your certificate now and access it any time from your Dashboard and Profile.",
|
||||
"progress.certificateStatus.downloadableBody": "Showcase your accomplishment on LinkedIn or your resumé today. You can download your certificate now and access it any time from your Dashboard and Profile.",
|
||||
"courseCelebration.certificateBody.notAvailable.endDate": "This course ended on {endDate} and final grades and certificates are scheduled to be\n available after {certAvailableDate}.",
|
||||
"progress.certificateStatus.notPassingHeader": "Certificate status",
|
||||
"progress.certificateStatus.notPassingBody": "In order to qualify for a certificate, you must have a passing grade.",
|
||||
@@ -300,11 +309,15 @@
|
||||
"learn.contentLock.content.locked": "Content Locked",
|
||||
"learn.contentLock.complete.prerequisite": "You must complete the prerequisite: '{prereqSectionName}' to access this content.",
|
||||
"learn.contentLock.goToSection": "Go To Prerequisite Section",
|
||||
"learn.hiddenAfterDue.gradeAvailable": "If you have completed this assignment, your grade is available on the {progressPage}.",
|
||||
"learn.hiddenAfterDue.header": "The due date for this assignment has passed.",
|
||||
"learn.hiddenAfterDue.description": "Because the due date has passed, this assignment is no longer available.",
|
||||
"learn.hiddenAfterDue.progressPage": "progress page",
|
||||
"learn.honorCode.content": "Honesty and academic integrity are important to {siteName} and the institutions providing courses and programs on the {siteName} site. By clicking “I agree” below, I confirm that I have read, understand, and will abide by the {link} for the {siteName} Site.",
|
||||
"learn.honorCode.name": "Honor Code",
|
||||
"learn.honorCode.cancel": "Cancel",
|
||||
"learn.honorCode.agree": "I agree",
|
||||
"gatedContent.paragraph.bulletOne": "Earn a {verifiedCertLink} of completion to showcase on your resume",
|
||||
"gatedContent.paragraph.bulletOne": "Earn a {verifiedCertLink} of completion to showcase on your resumé",
|
||||
"gatedContent.paragraph.bulletTwo": "Unlock access to all course activities, including {gradedAssignments}",
|
||||
"gatedContent.paragraph.bulletThree": "{fullAccess} to course content and materials, even after the course ends",
|
||||
"gatedContent.paragraph.bulletFour": "Support our {nonProfitMission} at edX",
|
||||
@@ -341,7 +354,7 @@
|
||||
"learning.upgradeButton.buttonText": "Upgrade for {pricing}",
|
||||
"learning.upgradeNowButton.buttonText": "Upgrade now for {pricing}",
|
||||
"learning.generic.upgradeNotification.verifiedCertLink": "verified certificate",
|
||||
"learning.generic.upgradeNotification.verifiedCertMessage": "Earn a {verifiedCertLink} of completion to showcase on your resume",
|
||||
"learning.generic.upgradeNotification.verifiedCertMessage": "Earn a {verifiedCertLink} of completion to showcase on your resumé",
|
||||
"learning.generic.upgradeNotification.noFBE.nonProfitMission": "Support our {nonProfitMission} at edX",
|
||||
"learning.generic.upgradeNotification.gradedAssignments": "graded assignments",
|
||||
"learning.generic.upgradeNotification.verifiedCertLink.fullAccess": "Full access",
|
||||
@@ -380,7 +393,7 @@
|
||||
"learning.streakCelebration.streakDiscountMessage": "You’ve unlocked a 15% off discount when you upgrade this course for a limited time only.",
|
||||
"learning.streakcelebration.factoida": "Users who learn {streak_length} days in a row {bolded_section} than those who don’t.",
|
||||
"learning.streakcelebration.factoidb": "Users who learn {streak_length} days in a row {bolded_section} vs. those who don’t.",
|
||||
"learning.streakCelebration.streakAA759EndDateMessage": "Ends {date}.",
|
||||
"learning.streakCelebration.streakCelebrationCouponEndDateMessage": "Ends {date}.",
|
||||
"learning.loading.failure": "There was an error loading this course.",
|
||||
"learning.loading": "Loading course page…"
|
||||
}
|
||||
@@ -10,7 +10,7 @@ import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { Switch } from 'react-router-dom';
|
||||
|
||||
import Footer, { messages as footerMessages } from '@edx/frontend-component-footer';
|
||||
import { messages as footerMessages } from '@edx/frontend-component-footer';
|
||||
|
||||
import appMessages from './i18n';
|
||||
import { UserMessagesProvider } from './generic/user-messages';
|
||||
@@ -21,60 +21,64 @@ import { CourseExit } from './courseware/course/course-exit';
|
||||
import CoursewareContainer from './courseware';
|
||||
import CoursewareRedirectLandingPage from './courseware/CoursewareRedirectLandingPage';
|
||||
import DatesTab from './course-home/dates-tab';
|
||||
import GoalUnsubscribe from './course-home/goal-unsubscribe';
|
||||
import ProgressTab from './course-home/progress-tab/ProgressTab';
|
||||
import { TabContainer } from './tab-page';
|
||||
|
||||
import { fetchDatesTab, fetchOutlineTab, fetchProgressTab } from './course-home/data';
|
||||
import { fetchCourse } from './courseware/data';
|
||||
import initializeStore from './store';
|
||||
import NoticesProvider from './generic/notices';
|
||||
|
||||
subscribe(APP_READY, () => {
|
||||
ReactDOM.render(
|
||||
<AppProvider store={initializeStore()}>
|
||||
<UserMessagesProvider>
|
||||
<Switch>
|
||||
<PageRoute path="/redirect" component={CoursewareRedirectLandingPage} />
|
||||
<PageRoute path="/course/:courseId/home">
|
||||
<TabContainer tab="outline" fetch={fetchOutlineTab} slice="courseHome">
|
||||
<OutlineTab />
|
||||
</TabContainer>
|
||||
</PageRoute>
|
||||
<PageRoute path="/course/:courseId/dates">
|
||||
<TabContainer tab="dates" fetch={fetchDatesTab} slice="courseHome">
|
||||
<DatesTab />
|
||||
</TabContainer>
|
||||
</PageRoute>
|
||||
<PageRoute
|
||||
path={[
|
||||
'/course/:courseId/progress/:targetUserId/',
|
||||
'/course/:courseId/progress',
|
||||
]}
|
||||
render={({ match }) => (
|
||||
<TabContainer
|
||||
tab="progress"
|
||||
fetch={(courseId) => fetchProgressTab(courseId, match.params.targetUserId)}
|
||||
slice="courseHome"
|
||||
>
|
||||
<ProgressTab />
|
||||
<NoticesProvider>
|
||||
<UserMessagesProvider>
|
||||
<Switch>
|
||||
<PageRoute exact path="/goal-unsubscribe/:token" component={GoalUnsubscribe} />
|
||||
<PageRoute path="/redirect" component={CoursewareRedirectLandingPage} />
|
||||
<PageRoute path="/course/:courseId/home">
|
||||
<TabContainer tab="outline" fetch={fetchOutlineTab} slice="courseHome">
|
||||
<OutlineTab />
|
||||
</TabContainer>
|
||||
)}
|
||||
/>
|
||||
<PageRoute path="/course/:courseId/course-end">
|
||||
<TabContainer tab="courseware" fetch={fetchCourse} slice="courseware">
|
||||
<CourseExit />
|
||||
</TabContainer>
|
||||
</PageRoute>
|
||||
<PageRoute
|
||||
path={[
|
||||
'/course/:courseId/:sequenceId/:unitId',
|
||||
'/course/:courseId/:sequenceId',
|
||||
'/course/:courseId',
|
||||
]}
|
||||
component={CoursewareContainer}
|
||||
/>
|
||||
</Switch>
|
||||
<Footer />
|
||||
</UserMessagesProvider>
|
||||
</PageRoute>
|
||||
<PageRoute path="/course/:courseId/dates">
|
||||
<TabContainer tab="dates" fetch={fetchDatesTab} slice="courseHome">
|
||||
<DatesTab />
|
||||
</TabContainer>
|
||||
</PageRoute>
|
||||
<PageRoute
|
||||
path={[
|
||||
'/course/:courseId/progress/:targetUserId/',
|
||||
'/course/:courseId/progress',
|
||||
]}
|
||||
render={({ match }) => (
|
||||
<TabContainer
|
||||
tab="progress"
|
||||
fetch={(courseId) => fetchProgressTab(courseId, match.params.targetUserId)}
|
||||
slice="courseHome"
|
||||
>
|
||||
<ProgressTab />
|
||||
</TabContainer>
|
||||
)}
|
||||
/>
|
||||
<PageRoute path="/course/:courseId/course-end">
|
||||
<TabContainer tab="courseware" fetch={fetchCourse} slice="courseware">
|
||||
<CourseExit />
|
||||
</TabContainer>
|
||||
</PageRoute>
|
||||
<PageRoute
|
||||
path={[
|
||||
'/course/:courseId/:sequenceId/:unitId',
|
||||
'/course/:courseId/:sequenceId',
|
||||
'/course/:courseId',
|
||||
]}
|
||||
component={CoursewareContainer}
|
||||
/>
|
||||
</Switch>
|
||||
</UserMessagesProvider>
|
||||
</NoticesProvider>
|
||||
</AppProvider>,
|
||||
document.getElementById('root'),
|
||||
);
|
||||
@@ -88,8 +92,10 @@ initialize({
|
||||
handlers: {
|
||||
config: () => {
|
||||
mergeConfig({
|
||||
CONTACT_URL: process.env.CONTACT_URL || null,
|
||||
CREDENTIALS_BASE_URL: process.env.CREDENTIALS_BASE_URL || null,
|
||||
ENTERPRISE_LEARNER_PORTAL_HOSTNAME: process.env.ENTERPRISE_LEARNER_PORTAL_HOSTNAME || null,
|
||||
ENABLE_NOTICES: process.env.ENABLE_NOTICES || null,
|
||||
INSIGHTS_BASE_URL: process.env.INSIGHTS_BASE_URL || null,
|
||||
SEARCH_CATALOG_URL: process.env.SEARCH_CATALOG_URL || null,
|
||||
SOCIAL_UTM_MILESTONE_CAMPAIGN: process.env.SOCIAL_UTM_MILESTONE_CAMPAIGN || null,
|
||||
@@ -98,6 +104,7 @@ initialize({
|
||||
SUPPORT_URL_CALCULATOR_MATH: process.env.SUPPORT_URL_CALCULATOR_MATH || null,
|
||||
SUPPORT_URL_ID_VERIFICATION: process.env.SUPPORT_URL_ID_VERIFICATION || null,
|
||||
SUPPORT_URL_VERIFIED_CERTIFICATE: process.env.SUPPORT_URL_VERIFIED_CERTIFICATE || null,
|
||||
TERMS_OF_SERVICE_URL: process.env.TERMS_OF_SERVICE_URL || null,
|
||||
TWITTER_HASHTAG: process.env.TWITTER_HASHTAG || null,
|
||||
TWITTER_URL: process.env.TWITTER_URL || null,
|
||||
}, 'LearnerAppConfig');
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user