Compare commits
29 Commits
alangsto/e
...
open-relea
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
83565059dd | ||
|
|
c8a95eb93d | ||
|
|
7bb75dd256 | ||
|
|
d76c0cc6ea | ||
|
|
1c3610e9af | ||
|
|
796bbef10b | ||
|
|
799e57f970 | ||
|
|
cf3a91dde0 | ||
|
|
72381a783b | ||
|
|
75f56ea4bd | ||
|
|
a418ba6adb | ||
|
|
2da930f819 | ||
|
|
a2c38112fb | ||
|
|
36535d188d | ||
|
|
79f49032e3 | ||
|
|
9b3b123e45 | ||
|
|
98436b4605 | ||
|
|
7652fa46d1 | ||
|
|
2347ce88cd | ||
|
|
78e5c57bd3 | ||
|
|
108636761c | ||
|
|
5f56828bda | ||
|
|
23e522e893 | ||
|
|
9423a889ba | ||
|
|
85b95adb9f | ||
|
|
d4e7b416b1 | ||
|
|
0cb369af2b | ||
|
|
c908d3a3dd | ||
|
|
895a3b6b9f |
2
.env
2
.env
@@ -4,7 +4,6 @@
|
||||
NODE_ENV='production'
|
||||
|
||||
ACCESS_TOKEN_COOKIE_NAME=''
|
||||
AI_TRANSLATIONS_URL=''
|
||||
BASE_URL=''
|
||||
CONTACT_URL=''
|
||||
CREDENTIALS_BASE_URL=''
|
||||
@@ -14,7 +13,6 @@ DISCOVERY_API_BASE_URL=''
|
||||
DISCUSSIONS_MFE_BASE_URL=''
|
||||
ECOMMERCE_BASE_URL=''
|
||||
ENABLE_JUMPNAV='true'
|
||||
ENABLE_NEW_SIDEBAR=''
|
||||
ENABLE_NOTICES=''
|
||||
ENTERPRISE_LEARNER_PORTAL_HOSTNAME=''
|
||||
EXAMS_BASE_URL=''
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
NODE_ENV='development'
|
||||
|
||||
ACCESS_TOKEN_COOKIE_NAME='edx-jwt-cookie-header-payload'
|
||||
AI_TRANSLATIONS_URL='http://localhost:18760'
|
||||
BASE_URL='http://localhost:2000'
|
||||
CONTACT_URL='http://localhost:18000/contact'
|
||||
CREDENTIALS_BASE_URL='http://localhost:18150'
|
||||
@@ -14,7 +13,6 @@ DISCOVERY_API_BASE_URL='http://localhost:18381'
|
||||
DISCUSSIONS_MFE_BASE_URL='http://localhost:2002'
|
||||
ECOMMERCE_BASE_URL='http://localhost:18130'
|
||||
ENABLE_JUMPNAV='true'
|
||||
ENABLE_NEW_SIDEBAR=''
|
||||
ENABLE_NOTICES=''
|
||||
ENTERPRISE_LEARNER_PORTAL_HOSTNAME='localhost:8734'
|
||||
EXAMS_BASE_URL=''
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
NODE_ENV='test'
|
||||
|
||||
ACCESS_TOKEN_COOKIE_NAME='edx-jwt-cookie-header-payload'
|
||||
AI_TRANSLATIONS_URL='http://localhost:18760'
|
||||
BASE_URL='http://localhost:2000'
|
||||
CONTACT_URL='http://localhost:18000/contact'
|
||||
CREDENTIALS_BASE_URL='http://localhost:18150'
|
||||
@@ -14,7 +13,6 @@ DISCOVERY_API_BASE_URL='http://localhost:18381'
|
||||
DISCUSSIONS_MFE_BASE_URL='http://localhost:2002'
|
||||
ECOMMERCE_BASE_URL='http://localhost:18130'
|
||||
ENABLE_JUMPNAV='true'
|
||||
ENABLE_NEW_SIDEBAR=''
|
||||
ENABLE_NOTICES=''
|
||||
ENTERPRISE_LEARNER_PORTAL_HOSTNAME='localhost:8734'
|
||||
EXAMS_BASE_URL='http://localhost:18740'
|
||||
|
||||
@@ -3,3 +3,5 @@ dist/
|
||||
packages/
|
||||
node_modules/
|
||||
jest.config.js
|
||||
env.config.jsx
|
||||
example.env.config.jsx
|
||||
|
||||
3
.github/workflows/validate.yml
vendored
3
.github/workflows/validate.yml
vendored
@@ -18,6 +18,7 @@ jobs:
|
||||
node-version: ${{ env.NODE_VER }}
|
||||
- run: make validate.ci
|
||||
- name: Upload coverage
|
||||
uses: codecov/codecov-action@v3
|
||||
uses: codecov/codecov-action@v4
|
||||
with:
|
||||
fail_ci_if_error: true
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
@@ -100,6 +100,12 @@ The Learning MFE is similar to all the other Open edX MFEs. Read the Open
|
||||
edX Developer Guide's section on
|
||||
`MFE applications <https://edx.readthedocs.io/projects/edx-developer-docs/en/latest/developers_guide/micro_frontends_in_open_edx.html>`_.
|
||||
|
||||
Plugins
|
||||
=======
|
||||
This MFE can be customized using `Frontend Plugin Framework <https://github.com/openedx/frontend-plugin-framework>`_.
|
||||
|
||||
The parts of this MFE that can be customized in that manner are documented `here </src/plugin-slots>`_.
|
||||
|
||||
Environment Variables
|
||||
======================
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import UnitTranslationPlugin from '@plugins/UnitTranslationPlugin';
|
||||
import UnitTranslationPlugin from '@edx/unit-translation-selector-plugin';
|
||||
import { PLUGIN_OPERATIONS, DIRECT_PLUGIN } from '@openedx/frontend-plugin-framework';
|
||||
|
||||
// Load environment variables from .env file
|
||||
|
||||
@@ -15,7 +15,6 @@ const config = createConfig('jest', {
|
||||
// See https://stackoverflow.com/questions/72382316/jest-encountered-an-unexpected-token-react-markdown
|
||||
'react-markdown': '<rootDir>/node_modules/react-markdown/react-markdown.min.js',
|
||||
'@src/(.*)': '<rootDir>/src/$1',
|
||||
'@plugins/(.*)': '<rootDir>/plugins/$1',
|
||||
},
|
||||
testTimeout: 30000,
|
||||
globalSetup: "./global-setup.js",
|
||||
|
||||
4911
package-lock.json
generated
4911
package-lock.json
generated
@@ -14,13 +14,13 @@
|
||||
"": {
|
||||
"name": "@edx/frontend-app-learning",
|
||||
"version": "1.0.0-semantically-released",
|
||||
"hasInstallScript": true,
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"@edx/brand": "npm:@openedx/brand-openedx@^1.2.2",
|
||||
"@edx/frontend-component-footer": "^13.0.4",
|
||||
"@edx/frontend-component-header": "^5.0.2",
|
||||
"@edx/frontend-lib-learning-assistant": "^2.0.0",
|
||||
"@edx/frontend-lib-special-exams": "^3.0.0",
|
||||
"@edx/frontend-lib-special-exams": "^3.0.1",
|
||||
"@edx/frontend-platform": "^7.1.2",
|
||||
"@edx/openedx-atlas": "^0.6.0",
|
||||
"@edx/react-unit-test-utils": "^2.0.0",
|
||||
@@ -29,8 +29,9 @@
|
||||
"@fortawesome/free-regular-svg-icons": "5.15.4",
|
||||
"@fortawesome/free-solid-svg-icons": "5.15.4",
|
||||
"@fortawesome/react-fontawesome": "^0.1.4",
|
||||
"@openedx/frontend-plugin-framework": "^1.0.2",
|
||||
"@openedx/paragon": "^22.1.1",
|
||||
"@openedx/frontend-plugin-framework": "^1.1.2",
|
||||
"@openedx/frontend-slot-footer": "^1.0.2",
|
||||
"@openedx/paragon": "^22.3.0",
|
||||
"@popperjs/core": "2.11.8",
|
||||
"@reduxjs/toolkit": "1.8.1",
|
||||
"classnames": "2.3.2",
|
||||
@@ -57,7 +58,7 @@
|
||||
"devDependencies": {
|
||||
"@edx/browserslist-config": "1.2.0",
|
||||
"@edx/reactifex": "2.2.0",
|
||||
"@openedx/frontend-build": "13.0.28",
|
||||
"@openedx/frontend-build": "13.1.4",
|
||||
"@pact-foundation/pact": "^11.0.2",
|
||||
"@testing-library/jest-dom": "5.16.5",
|
||||
"@testing-library/react": "12.1.5",
|
||||
@@ -71,6 +72,7 @@
|
||||
"jest": "^26.6.3",
|
||||
"jest-console-group-reporter": "^1.0.1",
|
||||
"jest-when": "^3.6.0",
|
||||
"patch-package": "^8.0.0",
|
||||
"postcss-loader": "^8.1.1",
|
||||
"rosie": "2.1.1",
|
||||
"sass": "^1.72.0",
|
||||
@@ -2059,10 +2061,18 @@
|
||||
"node": ">=0.1.90"
|
||||
}
|
||||
},
|
||||
"node_modules/@cospired/i18n-iso-languages": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@cospired/i18n-iso-languages/-/i18n-iso-languages-4.2.0.tgz",
|
||||
"integrity": "sha512-vy8cq1176MTxVwB1X9niQjcIYOH29F8Huxtx8hLmT5Uz3l1ztGDGri8KN/4zE7LV2mCT7JrcAoNV/I9yb+lNUw==",
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@csstools/cascade-layer-name-parser": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-1.0.6.tgz",
|
||||
"integrity": "sha512-HkxRNs6ZIV0VjLFw6k5G8K35vd9r+O8B1Vr+QVD8M5Y44eQxyHtc42BdF74FQatXACPnitOR1+sRx2oWdnKTQw==",
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-1.0.9.tgz",
|
||||
"integrity": "sha512-RRqNjxTZDUhx7pxYOBG/AkCVmPS3zYzfE47GEhIGkFuWFTQGJBgWOUUkKNo5MfxIfjDz5/1L3F3rF1oIsYaIpw==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@@ -2077,14 +2087,14 @@
|
||||
"node": "^14 || ^16 || >=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@csstools/css-parser-algorithms": "^2.4.0",
|
||||
"@csstools/css-tokenizer": "^2.2.2"
|
||||
"@csstools/css-parser-algorithms": "^2.6.1",
|
||||
"@csstools/css-tokenizer": "^2.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@csstools/css-parser-algorithms": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.4.0.tgz",
|
||||
"integrity": "sha512-/PPLr2g5PAUCKAPEbfyk6/baZA+WJHQtUhPkoCQMpyRE8I0lXrG1QFRN8e5s3ZYxM8d/g5BZc6lH3s8Op7/VEg==",
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.6.1.tgz",
|
||||
"integrity": "sha512-ubEkAaTfVZa+WwGhs5jbo5Xfqpeaybr/RvWzvFxRs4jfq16wH8l8Ty/QEEpINxll4xhuGfdMbipRyz5QZh9+FA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@@ -2099,13 +2109,13 @@
|
||||
"node": "^14 || ^16 || >=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@csstools/css-tokenizer": "^2.2.2"
|
||||
"@csstools/css-tokenizer": "^2.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@csstools/css-tokenizer": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.2.2.tgz",
|
||||
"integrity": "sha512-wCDUe/MAw7npAHFLyW3QjSyLA66S5QFaV1jIXlNQvdJ8RzXDSgALa49eWcUO6P55ARQaz0TsDdAgdRgkXFYY8g==",
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.2.4.tgz",
|
||||
"integrity": "sha512-PuWRAewQLbDhGeTvFuq2oClaSCKPIBmHyIobCV39JHRYN0byDcUWJl5baPeNUcqrjtdMNqFooE0FGl31I3JOqw==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@@ -2121,9 +2131,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@csstools/media-query-list-parser": {
|
||||
"version": "2.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.6.tgz",
|
||||
"integrity": "sha512-R6AKl9vaU0It7D7TR2lQn0pre5aQfdeqHRePlaRCY8rHL3l9eVlNRpsEVDKFi/zAjzv68CxH2M5kqbhPFPKjvw==",
|
||||
"version": "2.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.9.tgz",
|
||||
"integrity": "sha512-qqGuFfbn4rUmyOB0u8CVISIp5FfJ5GAR3mBrZ9/TKndHakdnm6pY0L/fbLcpPnrzwCyyTEZl1nUcXAYHEWneTA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@@ -2138,8 +2148,8 @@
|
||||
"node": "^14 || ^16 || >=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@csstools/css-parser-algorithms": "^2.4.0",
|
||||
"@csstools/css-tokenizer": "^2.2.2"
|
||||
"@csstools/css-parser-algorithms": "^2.6.1",
|
||||
"@csstools/css-tokenizer": "^2.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@dabh/diagnostics": {
|
||||
@@ -2186,19 +2196,22 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer": {
|
||||
"version": "13.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-component-footer/-/frontend-component-footer-13.0.4.tgz",
|
||||
"integrity": "sha512-E7KvzCXBmeH7bI6CHrZs/V4ARTAKsvX4tcFROtx9S9F35OvwvkZLxfyuuYgPfgNTTZtYqpoUcef1B7LQUlxLbw==",
|
||||
"version": "14.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-component-footer/-/frontend-component-footer-14.0.0.tgz",
|
||||
"integrity": "sha512-3Riz6ippBnPz1oq6gZgFBx27bJkNL+rwwKrv0uCuHV/5MscS1aYeKx1ZAMuUsxkKcGX6uhyU6PwM6agvnhKfNQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "6.5.1",
|
||||
"@fortawesome/free-brands-svg-icons": "6.5.1",
|
||||
"@fortawesome/free-regular-svg-icons": "6.5.1",
|
||||
"@fortawesome/free-solid-svg-icons": "6.5.1",
|
||||
"@fortawesome/fontawesome-svg-core": "6.5.2",
|
||||
"@fortawesome/free-brands-svg-icons": "6.5.2",
|
||||
"@fortawesome/free-regular-svg-icons": "6.5.2",
|
||||
"@fortawesome/free-solid-svg-icons": "6.5.2",
|
||||
"@fortawesome/react-fontawesome": "0.2.0",
|
||||
"lodash": "^4.17.21"
|
||||
"jest-environment-jsdom": "^29.7.0",
|
||||
"lodash": "^4.17.21",
|
||||
"ts-jest": "^29.1.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@edx/frontend-platform": "^7.0.0",
|
||||
"@edx/frontend-platform": "^7.0.0 || ^8.0.0",
|
||||
"@openedx/paragon": ">= 21.11.3 < 23.0.0",
|
||||
"prop-types": "^15.5.10",
|
||||
"react": "^16.9.0 || ^17.0.0",
|
||||
@@ -2206,57 +2219,62 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/@fortawesome/fontawesome-common-types": {
|
||||
"version": "6.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.1.tgz",
|
||||
"integrity": "sha512-GkWzv+L6d2bI5f/Vk6ikJ9xtl7dfXtoRu3YGE6nq0p/FFqA1ebMOAWg3XgRyb0I6LYyYkiAo+3/KrwuBp8xG7A==",
|
||||
"version": "6.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.2.tgz",
|
||||
"integrity": "sha512-gBxPg3aVO6J0kpfHNILc+NMhXnqHumFxOmjYCFfOiLZfwhnnfhtsdA2hfJlDnj+8PjAs6kKQPenOTKj3Rf7zHw==",
|
||||
"hasInstallScript": true,
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/@fortawesome/fontawesome-svg-core": {
|
||||
"version": "6.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.5.1.tgz",
|
||||
"integrity": "sha512-MfRCYlQPXoLlpem+egxjfkEuP9UQswTrlCOsknus/NcMoblTH2g0jPrapbcIb04KGA7E2GZxbAccGZfWoYgsrQ==",
|
||||
"version": "6.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.5.2.tgz",
|
||||
"integrity": "sha512-5CdaCBGl8Rh9ohNdxeeTMxIj8oc3KNBgIeLMvJosBMdslK/UnEB8rzyDRrbKdL1kDweqBPo4GT9wvnakHWucZw==",
|
||||
"hasInstallScript": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-common-types": "6.5.1"
|
||||
"@fortawesome/fontawesome-common-types": "6.5.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/@fortawesome/free-brands-svg-icons": {
|
||||
"version": "6.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.5.1.tgz",
|
||||
"integrity": "sha512-093l7DAkx0aEtBq66Sf19MgoZewv1zeY9/4C7vSKPO4qMwEsW/2VYTUTpBtLwfb9T2R73tXaRDPmE4UqLCYHfg==",
|
||||
"version": "6.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.5.2.tgz",
|
||||
"integrity": "sha512-zi5FNYdmKLnEc0jc0uuHH17kz/hfYTg4Uei0wMGzcoCL/4d3WM3u1VMc0iGGa31HuhV5i7ZK8ZlTCQrHqRHSGQ==",
|
||||
"hasInstallScript": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-common-types": "6.5.1"
|
||||
"@fortawesome/fontawesome-common-types": "6.5.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/@fortawesome/free-regular-svg-icons": {
|
||||
"version": "6.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.5.1.tgz",
|
||||
"integrity": "sha512-m6ShXn+wvqEU69wSP84coxLbNl7sGVZb+Ca+XZq6k30SzuP3X4TfPqtycgUh9ASwlNh5OfQCd8pDIWxl+O+LlQ==",
|
||||
"version": "6.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.5.2.tgz",
|
||||
"integrity": "sha512-iabw/f5f8Uy2nTRtJ13XZTS1O5+t+anvlamJ3zJGLEVE2pKsAWhPv2lq01uQlfgCX7VaveT3EVs515cCN9jRbw==",
|
||||
"hasInstallScript": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-common-types": "6.5.1"
|
||||
"@fortawesome/fontawesome-common-types": "6.5.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/@fortawesome/free-solid-svg-icons": {
|
||||
"version": "6.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.5.1.tgz",
|
||||
"integrity": "sha512-S1PPfU3mIJa59biTtXJz1oI0+KAXW6bkAb31XKhxdxtuXDiUIFsih4JR1v5BbxY7hVHsD1RKq+jRkVRaf773NQ==",
|
||||
"version": "6.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.5.2.tgz",
|
||||
"integrity": "sha512-QWFZYXFE7O1Gr1dTIp+D6UcFUF0qElOnZptpi7PBUMylJh+vFmIedVe1Ir6RM1t2tEQLLSV1k7bR4o92M+uqlw==",
|
||||
"hasInstallScript": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-common-types": "6.5.1"
|
||||
"@fortawesome/fontawesome-common-types": "6.5.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
@@ -2266,6 +2284,7 @@
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.0.tgz",
|
||||
"integrity": "sha512-uHg75Rb/XORTtVt7OS9WoK8uM276Ufi7gCzshVWkUJbHhh3svsUUeqXerrM96Wm7fRiDzfKRwSoahhMIkGAYHw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"prop-types": "^15.8.1"
|
||||
},
|
||||
@@ -2274,6 +2293,1076 @@
|
||||
"react": ">=16.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/@jest/core": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz",
|
||||
"integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/console": "^29.7.0",
|
||||
"@jest/reporters": "^29.7.0",
|
||||
"@jest/test-result": "^29.7.0",
|
||||
"@jest/transform": "^29.7.0",
|
||||
"@jest/types": "^29.6.3",
|
||||
"@types/node": "*",
|
||||
"ansi-escapes": "^4.2.1",
|
||||
"chalk": "^4.0.0",
|
||||
"ci-info": "^3.2.0",
|
||||
"exit": "^0.1.2",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"jest-changed-files": "^29.7.0",
|
||||
"jest-config": "^29.7.0",
|
||||
"jest-haste-map": "^29.7.0",
|
||||
"jest-message-util": "^29.7.0",
|
||||
"jest-regex-util": "^29.6.3",
|
||||
"jest-resolve": "^29.7.0",
|
||||
"jest-resolve-dependencies": "^29.7.0",
|
||||
"jest-runner": "^29.7.0",
|
||||
"jest-runtime": "^29.7.0",
|
||||
"jest-snapshot": "^29.7.0",
|
||||
"jest-util": "^29.7.0",
|
||||
"jest-validate": "^29.7.0",
|
||||
"jest-watcher": "^29.7.0",
|
||||
"micromatch": "^4.0.4",
|
||||
"pretty-format": "^29.7.0",
|
||||
"slash": "^3.0.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"node-notifier": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/@jest/environment": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz",
|
||||
"integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/fake-timers": "^29.7.0",
|
||||
"@jest/types": "^29.6.3",
|
||||
"@types/node": "*",
|
||||
"jest-mock": "^29.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/@jest/fake-timers": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz",
|
||||
"integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/types": "^29.6.3",
|
||||
"@sinonjs/fake-timers": "^10.0.2",
|
||||
"@types/node": "*",
|
||||
"jest-message-util": "^29.7.0",
|
||||
"jest-mock": "^29.7.0",
|
||||
"jest-util": "^29.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/@jest/globals": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz",
|
||||
"integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/environment": "^29.7.0",
|
||||
"@jest/expect": "^29.7.0",
|
||||
"@jest/types": "^29.6.3",
|
||||
"jest-mock": "^29.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/@jest/source-map": {
|
||||
"version": "29.6.3",
|
||||
"resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz",
|
||||
"integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/trace-mapping": "^0.3.18",
|
||||
"callsites": "^3.0.0",
|
||||
"graceful-fs": "^4.2.9"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/@jest/test-sequencer": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz",
|
||||
"integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/test-result": "^29.7.0",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"jest-haste-map": "^29.7.0",
|
||||
"slash": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/@jest/transform": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz",
|
||||
"integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.11.6",
|
||||
"@jest/types": "^29.6.3",
|
||||
"@jridgewell/trace-mapping": "^0.3.18",
|
||||
"babel-plugin-istanbul": "^6.1.1",
|
||||
"chalk": "^4.0.0",
|
||||
"convert-source-map": "^2.0.0",
|
||||
"fast-json-stable-stringify": "^2.1.0",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"jest-haste-map": "^29.7.0",
|
||||
"jest-regex-util": "^29.6.3",
|
||||
"jest-util": "^29.7.0",
|
||||
"micromatch": "^4.0.4",
|
||||
"pirates": "^4.0.4",
|
||||
"slash": "^3.0.0",
|
||||
"write-file-atomic": "^4.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/@jest/types": {
|
||||
"version": "29.6.3",
|
||||
"resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
|
||||
"integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/schemas": "^29.6.3",
|
||||
"@types/istanbul-lib-coverage": "^2.0.0",
|
||||
"@types/istanbul-reports": "^3.0.0",
|
||||
"@types/node": "*",
|
||||
"@types/yargs": "^17.0.8",
|
||||
"chalk": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/@sinonjs/commons": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz",
|
||||
"integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"type-detect": "4.0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/@sinonjs/fake-timers": {
|
||||
"version": "10.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz",
|
||||
"integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@sinonjs/commons": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/@tootallnate/once": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
|
||||
"integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/@types/yargs": {
|
||||
"version": "17.0.32",
|
||||
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz",
|
||||
"integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/yargs-parser": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/acorn-globals": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz",
|
||||
"integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"acorn": "^8.1.0",
|
||||
"acorn-walk": "^8.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/ansi-styles": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
|
||||
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/babel-jest": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz",
|
||||
"integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/transform": "^29.7.0",
|
||||
"@types/babel__core": "^7.1.14",
|
||||
"babel-plugin-istanbul": "^6.1.1",
|
||||
"babel-preset-jest": "^29.6.3",
|
||||
"chalk": "^4.0.0",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"slash": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/babel-plugin-jest-hoist": {
|
||||
"version": "29.6.3",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz",
|
||||
"integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/template": "^7.3.3",
|
||||
"@babel/types": "^7.3.3",
|
||||
"@types/babel__core": "^7.1.14",
|
||||
"@types/babel__traverse": "^7.0.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/babel-preset-jest": {
|
||||
"version": "29.6.3",
|
||||
"resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz",
|
||||
"integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"babel-plugin-jest-hoist": "^29.6.3",
|
||||
"babel-preset-current-node-syntax": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/cjs-module-lexer": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz",
|
||||
"integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/convert-source-map": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
|
||||
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/cssom": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz",
|
||||
"integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/data-urls": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz",
|
||||
"integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"abab": "^2.0.6",
|
||||
"whatwg-mimetype": "^3.0.0",
|
||||
"whatwg-url": "^11.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/domexception": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz",
|
||||
"integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==",
|
||||
"deprecated": "Use your platform's native DOMException instead",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"webidl-conversions": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/emittery": {
|
||||
"version": "0.13.1",
|
||||
"resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz",
|
||||
"integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sindresorhus/emittery?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/html-encoding-sniffer": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz",
|
||||
"integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"whatwg-encoding": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/http-proxy-agent": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
|
||||
"integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@tootallnate/once": "2",
|
||||
"agent-base": "6",
|
||||
"debug": "4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/iconv-lite": {
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
||||
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/jest": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz",
|
||||
"integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/core": "^29.7.0",
|
||||
"@jest/types": "^29.6.3",
|
||||
"import-local": "^3.0.2",
|
||||
"jest-cli": "^29.7.0"
|
||||
},
|
||||
"bin": {
|
||||
"jest": "bin/jest.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"node-notifier": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/jest-changed-files": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz",
|
||||
"integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"execa": "^5.0.0",
|
||||
"jest-util": "^29.7.0",
|
||||
"p-limit": "^3.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/jest-cli": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz",
|
||||
"integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/core": "^29.7.0",
|
||||
"@jest/test-result": "^29.7.0",
|
||||
"@jest/types": "^29.6.3",
|
||||
"chalk": "^4.0.0",
|
||||
"create-jest": "^29.7.0",
|
||||
"exit": "^0.1.2",
|
||||
"import-local": "^3.0.2",
|
||||
"jest-config": "^29.7.0",
|
||||
"jest-util": "^29.7.0",
|
||||
"jest-validate": "^29.7.0",
|
||||
"yargs": "^17.3.1"
|
||||
},
|
||||
"bin": {
|
||||
"jest": "bin/jest.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"node-notifier": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/jest-config": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz",
|
||||
"integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.11.6",
|
||||
"@jest/test-sequencer": "^29.7.0",
|
||||
"@jest/types": "^29.6.3",
|
||||
"babel-jest": "^29.7.0",
|
||||
"chalk": "^4.0.0",
|
||||
"ci-info": "^3.2.0",
|
||||
"deepmerge": "^4.2.2",
|
||||
"glob": "^7.1.3",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"jest-circus": "^29.7.0",
|
||||
"jest-environment-node": "^29.7.0",
|
||||
"jest-get-type": "^29.6.3",
|
||||
"jest-regex-util": "^29.6.3",
|
||||
"jest-resolve": "^29.7.0",
|
||||
"jest-runner": "^29.7.0",
|
||||
"jest-util": "^29.7.0",
|
||||
"jest-validate": "^29.7.0",
|
||||
"micromatch": "^4.0.4",
|
||||
"parse-json": "^5.2.0",
|
||||
"pretty-format": "^29.7.0",
|
||||
"slash": "^3.0.0",
|
||||
"strip-json-comments": "^3.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/node": "*",
|
||||
"ts-node": ">=9.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/node": {
|
||||
"optional": true
|
||||
},
|
||||
"ts-node": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/jest-docblock": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz",
|
||||
"integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"detect-newline": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/jest-environment-jsdom": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.7.0.tgz",
|
||||
"integrity": "sha512-k9iQbsf9OyOfdzWH8HDmrRT0gSIcX+FLNW7IQq94tFX0gynPwqDTW0Ho6iMVNjGz/nb+l/vW3dWM2bbLLpkbXA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/environment": "^29.7.0",
|
||||
"@jest/fake-timers": "^29.7.0",
|
||||
"@jest/types": "^29.6.3",
|
||||
"@types/jsdom": "^20.0.0",
|
||||
"@types/node": "*",
|
||||
"jest-mock": "^29.7.0",
|
||||
"jest-util": "^29.7.0",
|
||||
"jsdom": "^20.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"canvas": "^2.5.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"canvas": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/jest-environment-node": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz",
|
||||
"integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/environment": "^29.7.0",
|
||||
"@jest/fake-timers": "^29.7.0",
|
||||
"@jest/types": "^29.6.3",
|
||||
"@types/node": "*",
|
||||
"jest-mock": "^29.7.0",
|
||||
"jest-util": "^29.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/jest-haste-map": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz",
|
||||
"integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/types": "^29.6.3",
|
||||
"@types/graceful-fs": "^4.1.3",
|
||||
"@types/node": "*",
|
||||
"anymatch": "^3.0.3",
|
||||
"fb-watchman": "^2.0.0",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"jest-regex-util": "^29.6.3",
|
||||
"jest-util": "^29.7.0",
|
||||
"jest-worker": "^29.7.0",
|
||||
"micromatch": "^4.0.4",
|
||||
"walker": "^1.0.8"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "^2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/jest-leak-detector": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz",
|
||||
"integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"jest-get-type": "^29.6.3",
|
||||
"pretty-format": "^29.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/jest-mock": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz",
|
||||
"integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/types": "^29.6.3",
|
||||
"@types/node": "*",
|
||||
"jest-util": "^29.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/jest-regex-util": {
|
||||
"version": "29.6.3",
|
||||
"resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz",
|
||||
"integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/jest-resolve": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz",
|
||||
"integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"chalk": "^4.0.0",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"jest-haste-map": "^29.7.0",
|
||||
"jest-pnp-resolver": "^1.2.2",
|
||||
"jest-util": "^29.7.0",
|
||||
"jest-validate": "^29.7.0",
|
||||
"resolve": "^1.20.0",
|
||||
"resolve.exports": "^2.0.0",
|
||||
"slash": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/jest-resolve-dependencies": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz",
|
||||
"integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"jest-regex-util": "^29.6.3",
|
||||
"jest-snapshot": "^29.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/jest-runner": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz",
|
||||
"integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/console": "^29.7.0",
|
||||
"@jest/environment": "^29.7.0",
|
||||
"@jest/test-result": "^29.7.0",
|
||||
"@jest/transform": "^29.7.0",
|
||||
"@jest/types": "^29.6.3",
|
||||
"@types/node": "*",
|
||||
"chalk": "^4.0.0",
|
||||
"emittery": "^0.13.1",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"jest-docblock": "^29.7.0",
|
||||
"jest-environment-node": "^29.7.0",
|
||||
"jest-haste-map": "^29.7.0",
|
||||
"jest-leak-detector": "^29.7.0",
|
||||
"jest-message-util": "^29.7.0",
|
||||
"jest-resolve": "^29.7.0",
|
||||
"jest-runtime": "^29.7.0",
|
||||
"jest-util": "^29.7.0",
|
||||
"jest-watcher": "^29.7.0",
|
||||
"jest-worker": "^29.7.0",
|
||||
"p-limit": "^3.1.0",
|
||||
"source-map-support": "0.5.13"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/jest-runtime": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz",
|
||||
"integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/environment": "^29.7.0",
|
||||
"@jest/fake-timers": "^29.7.0",
|
||||
"@jest/globals": "^29.7.0",
|
||||
"@jest/source-map": "^29.6.3",
|
||||
"@jest/test-result": "^29.7.0",
|
||||
"@jest/transform": "^29.7.0",
|
||||
"@jest/types": "^29.6.3",
|
||||
"@types/node": "*",
|
||||
"chalk": "^4.0.0",
|
||||
"cjs-module-lexer": "^1.0.0",
|
||||
"collect-v8-coverage": "^1.0.0",
|
||||
"glob": "^7.1.3",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"jest-haste-map": "^29.7.0",
|
||||
"jest-message-util": "^29.7.0",
|
||||
"jest-mock": "^29.7.0",
|
||||
"jest-regex-util": "^29.6.3",
|
||||
"jest-resolve": "^29.7.0",
|
||||
"jest-snapshot": "^29.7.0",
|
||||
"jest-util": "^29.7.0",
|
||||
"slash": "^3.0.0",
|
||||
"strip-bom": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/jest-snapshot": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz",
|
||||
"integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.11.6",
|
||||
"@babel/generator": "^7.7.2",
|
||||
"@babel/plugin-syntax-jsx": "^7.7.2",
|
||||
"@babel/plugin-syntax-typescript": "^7.7.2",
|
||||
"@babel/types": "^7.3.3",
|
||||
"@jest/expect-utils": "^29.7.0",
|
||||
"@jest/transform": "^29.7.0",
|
||||
"@jest/types": "^29.6.3",
|
||||
"babel-preset-current-node-syntax": "^1.0.0",
|
||||
"chalk": "^4.0.0",
|
||||
"expect": "^29.7.0",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"jest-diff": "^29.7.0",
|
||||
"jest-get-type": "^29.6.3",
|
||||
"jest-matcher-utils": "^29.7.0",
|
||||
"jest-message-util": "^29.7.0",
|
||||
"jest-util": "^29.7.0",
|
||||
"natural-compare": "^1.4.0",
|
||||
"pretty-format": "^29.7.0",
|
||||
"semver": "^7.5.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/jest-util": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz",
|
||||
"integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/types": "^29.6.3",
|
||||
"@types/node": "*",
|
||||
"chalk": "^4.0.0",
|
||||
"ci-info": "^3.2.0",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"picomatch": "^2.2.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/jest-validate": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz",
|
||||
"integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/types": "^29.6.3",
|
||||
"camelcase": "^6.2.0",
|
||||
"chalk": "^4.0.0",
|
||||
"jest-get-type": "^29.6.3",
|
||||
"leven": "^3.1.0",
|
||||
"pretty-format": "^29.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/jest-watcher": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz",
|
||||
"integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/test-result": "^29.7.0",
|
||||
"@jest/types": "^29.6.3",
|
||||
"@types/node": "*",
|
||||
"ansi-escapes": "^4.2.1",
|
||||
"chalk": "^4.0.0",
|
||||
"emittery": "^0.13.1",
|
||||
"jest-util": "^29.7.0",
|
||||
"string-length": "^4.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/jsdom": {
|
||||
"version": "20.0.3",
|
||||
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz",
|
||||
"integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"abab": "^2.0.6",
|
||||
"acorn": "^8.8.1",
|
||||
"acorn-globals": "^7.0.0",
|
||||
"cssom": "^0.5.0",
|
||||
"cssstyle": "^2.3.0",
|
||||
"data-urls": "^3.0.2",
|
||||
"decimal.js": "^10.4.2",
|
||||
"domexception": "^4.0.0",
|
||||
"escodegen": "^2.0.0",
|
||||
"form-data": "^4.0.0",
|
||||
"html-encoding-sniffer": "^3.0.0",
|
||||
"http-proxy-agent": "^5.0.0",
|
||||
"https-proxy-agent": "^5.0.1",
|
||||
"is-potential-custom-element-name": "^1.0.1",
|
||||
"nwsapi": "^2.2.2",
|
||||
"parse5": "^7.1.1",
|
||||
"saxes": "^6.0.0",
|
||||
"symbol-tree": "^3.2.4",
|
||||
"tough-cookie": "^4.1.2",
|
||||
"w3c-xmlserializer": "^4.0.0",
|
||||
"webidl-conversions": "^7.0.0",
|
||||
"whatwg-encoding": "^2.0.0",
|
||||
"whatwg-mimetype": "^3.0.0",
|
||||
"whatwg-url": "^11.0.0",
|
||||
"ws": "^8.11.0",
|
||||
"xml-name-validator": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"canvas": "^2.5.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"canvas": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/parse5": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz",
|
||||
"integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"entities": "^4.4.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/inikulin/parse5?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/pretty-format": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
|
||||
"integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/schemas": "^29.6.3",
|
||||
"ansi-styles": "^5.0.0",
|
||||
"react-is": "^18.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/react-is": {
|
||||
"version": "18.3.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
|
||||
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/saxes": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz",
|
||||
"integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"xmlchars": "^2.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=v12.22.7"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/semver": {
|
||||
"version": "7.6.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
|
||||
"integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/slash": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
|
||||
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/source-map-support": {
|
||||
"version": "0.5.13",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz",
|
||||
"integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"source-map": "^0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/tr46": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz",
|
||||
"integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"punycode": "^2.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/ts-jest": {
|
||||
"version": "29.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.2.tgz",
|
||||
"integrity": "sha512-br6GJoH/WUX4pu7FbZXuWGKGNDuU7b8Uj77g/Sp7puZV6EXzuByl6JrECvm0MzVzSTkSHWTihsXt+5XYER5b+g==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"bs-logger": "0.x",
|
||||
"fast-json-stable-stringify": "2.x",
|
||||
"jest-util": "^29.0.0",
|
||||
"json5": "^2.2.3",
|
||||
"lodash.memoize": "4.x",
|
||||
"make-error": "1.x",
|
||||
"semver": "^7.5.3",
|
||||
"yargs-parser": "^21.0.1"
|
||||
},
|
||||
"bin": {
|
||||
"ts-jest": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^16.10.0 || ^18.0.0 || >=20.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": ">=7.0.0-beta.0 <8",
|
||||
"@jest/types": "^29.0.0",
|
||||
"babel-jest": "^29.0.0",
|
||||
"jest": "^29.0.0",
|
||||
"typescript": ">=4.3 <6"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@babel/core": {
|
||||
"optional": true
|
||||
},
|
||||
"@jest/types": {
|
||||
"optional": true
|
||||
},
|
||||
"babel-jest": {
|
||||
"optional": true
|
||||
},
|
||||
"esbuild": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/w3c-xmlserializer": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz",
|
||||
"integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"xml-name-validator": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/webidl-conversions": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
|
||||
"integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/whatwg-encoding": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz",
|
||||
"integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"iconv-lite": "0.6.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/whatwg-mimetype": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz",
|
||||
"integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/whatwg-url": {
|
||||
"version": "11.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz",
|
||||
"integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tr46": "^3.0.0",
|
||||
"webidl-conversions": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/write-file-atomic": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz",
|
||||
"integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"imurmurhash": "^0.1.4",
|
||||
"signal-exit": "^3.0.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/ws": {
|
||||
"version": "8.17.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.0.tgz",
|
||||
"integrity": "sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"bufferutil": "^4.0.1",
|
||||
"utf-8-validate": ">=5.0.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"bufferutil": {
|
||||
"optional": true
|
||||
},
|
||||
"utf-8-validate": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-footer/node_modules/xml-name-validator": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz",
|
||||
"integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-component-header": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-component-header/-/frontend-component-header-5.0.2.tgz",
|
||||
@@ -2458,9 +3547,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-lib-special-exams": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-lib-special-exams/-/frontend-lib-special-exams-3.0.0.tgz",
|
||||
"integrity": "sha512-3uUuFfiiuLJyRjOpH12qIGT1LtUiN6GIRKbGGmDPv4ZVdQaRxI1oEXDArQ7bcuBD4VHw3rI/JcO31k9pkWScLA==",
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-lib-special-exams/-/frontend-lib-special-exams-3.0.1.tgz",
|
||||
"integrity": "sha512-9kW/sPECgtAg0VaIPaMuytAZQXbg4QdrKMEhwHWQF/sLRW7f33wBjZzWgyB62Aixc0fLceZDBUKC7VKzl0Qbdw==",
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "1.2.34",
|
||||
"@fortawesome/free-brands-svg-icons": "5.11.2",
|
||||
@@ -2550,9 +3639,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-platform": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-platform/-/frontend-platform-7.1.2.tgz",
|
||||
"integrity": "sha512-iKd8n6QoFjaATEfLOYe+gsJLHFoGWpZbX2Z4D6hM+OthTISE98K8+/7Gx7PAcT9vlJEA33OVIThncZYwYaaluw==",
|
||||
"version": "7.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-platform/-/frontend-platform-7.1.3.tgz",
|
||||
"integrity": "sha512-klw0pvFnAo8k8iVPxcR9WCPLaYqV2AFdnz1COF6hJ6gOIFuj2Mb5cuEy9di89INpZFO/0FEHq1IBVojm1rbJcg==",
|
||||
"dependencies": {
|
||||
"@cospired/i18n-iso-languages": "4.2.0",
|
||||
"@formatjs/intl-pluralrules": "4.3.3",
|
||||
@@ -2571,7 +3660,7 @@
|
||||
"lodash.merge": "4.6.2",
|
||||
"lodash.snakecase": "4.1.1",
|
||||
"pubsub-js": "1.9.4",
|
||||
"react-intl": "6.6.2",
|
||||
"react-intl": "6.6.3",
|
||||
"universal-cookie": "4.0.4"
|
||||
},
|
||||
"bin": {
|
||||
@@ -2589,53 +3678,6 @@
|
||||
"redux": "^4.0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-platform/node_modules/@cospired/i18n-iso-languages": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@cospired/i18n-iso-languages/-/i18n-iso-languages-4.2.0.tgz",
|
||||
"integrity": "sha512-vy8cq1176MTxVwB1X9niQjcIYOH29F8Huxtx8hLmT5Uz3l1ztGDGri8KN/4zE7LV2mCT7JrcAoNV/I9yb+lNUw==",
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-platform/node_modules/@formatjs/ecma402-abstract": {
|
||||
"version": "1.18.2",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.18.2.tgz",
|
||||
"integrity": "sha512-+QoPW4csYALsQIl8GbN14igZzDbuwzcpWrku9nyMXlaqAlwRBgl5V+p0vWMGFqHOw37czNXaP/lEk4wbLgcmtA==",
|
||||
"dependencies": {
|
||||
"@formatjs/intl-localematcher": "0.5.4",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-platform/node_modules/@formatjs/intl": {
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/intl/-/intl-2.10.0.tgz",
|
||||
"integrity": "sha512-X3xT9guVkKDS86EKV80lS0KxoazUglkJTGZO66sKY7otgl0VeStPA8B3u8UkKT47PexVV98fUzjpkchYmbe9nw==",
|
||||
"dependencies": {
|
||||
"@formatjs/ecma402-abstract": "1.18.2",
|
||||
"@formatjs/fast-memoize": "2.2.0",
|
||||
"@formatjs/icu-messageformat-parser": "2.7.6",
|
||||
"@formatjs/intl-displaynames": "6.6.6",
|
||||
"@formatjs/intl-listformat": "7.5.5",
|
||||
"intl-messageformat": "10.5.11",
|
||||
"tslib": "^2.4.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^4.7 || 5"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"typescript": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-platform/node_modules/@formatjs/intl-localematcher": {
|
||||
"version": "0.5.4",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.4.tgz",
|
||||
"integrity": "sha512-zTwEpWOzZ2CiKcB93BLngUX59hQkuZjT2+SAQEscSm52peDW/getsawMcWF1rGRpMCX6D7nSJA3CzJ8gn13N/g==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-platform/node_modules/axios": {
|
||||
"version": "0.27.2",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz",
|
||||
@@ -2658,32 +3700,6 @@
|
||||
"value-equal": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/frontend-platform/node_modules/react-intl": {
|
||||
"version": "6.6.2",
|
||||
"resolved": "https://registry.npmjs.org/react-intl/-/react-intl-6.6.2.tgz",
|
||||
"integrity": "sha512-IpW2IkLtGENSFlX3vfH11rjuCIsW0VyjT0Q1pPKMZPtT2z1FxLt4weFT5Ezti2TScT1xiyb3aQBFth9EB7jzAg==",
|
||||
"dependencies": {
|
||||
"@formatjs/ecma402-abstract": "1.18.2",
|
||||
"@formatjs/icu-messageformat-parser": "2.7.6",
|
||||
"@formatjs/intl": "2.10.0",
|
||||
"@formatjs/intl-displaynames": "6.6.6",
|
||||
"@formatjs/intl-listformat": "7.5.5",
|
||||
"@types/hoist-non-react-statics": "^3.3.1",
|
||||
"@types/react": "16 || 17 || 18",
|
||||
"hoist-non-react-statics": "^3.3.2",
|
||||
"intl-messageformat": "10.5.11",
|
||||
"tslib": "^2.4.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.6.0 || 17 || 18",
|
||||
"typescript": "^4.7 || 5"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"typescript": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/new-relic-source-map-webpack-plugin": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@edx/new-relic-source-map-webpack-plugin/-/new-relic-source-map-webpack-plugin-2.1.0.tgz",
|
||||
@@ -2972,7 +3988,6 @@
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/intl/-/intl-2.10.1.tgz",
|
||||
"integrity": "sha512-dsLG15U7xDi8yzKf4hcAWSsCaez3XrjTO2oaRHPyHtXLm1aEzYbDw6bClo/HMHu+iwS5GbDqT3DV+hYP2ylScg==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@formatjs/ecma402-abstract": "1.18.2",
|
||||
"@formatjs/fast-memoize": "2.2.0",
|
||||
@@ -3077,7 +4092,6 @@
|
||||
"version": "1.18.2",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.18.2.tgz",
|
||||
"integrity": "sha512-+QoPW4csYALsQIl8GbN14igZzDbuwzcpWrku9nyMXlaqAlwRBgl5V+p0vWMGFqHOw37czNXaP/lEk4wbLgcmtA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@formatjs/intl-localematcher": "0.5.4",
|
||||
"tslib": "^2.4.0"
|
||||
@@ -3087,7 +4101,6 @@
|
||||
"version": "0.5.4",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.4.tgz",
|
||||
"integrity": "sha512-zTwEpWOzZ2CiKcB93BLngUX59hQkuZjT2+SAQEscSm52peDW/getsawMcWF1rGRpMCX6D7nSJA3CzJ8gn13N/g==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
@@ -3327,7 +4340,6 @@
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz",
|
||||
"integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/types": "^29.6.3",
|
||||
@@ -3345,7 +4357,6 @@
|
||||
"version": "29.6.3",
|
||||
"resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
|
||||
"integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/schemas": "^29.6.3",
|
||||
@@ -3363,7 +4374,6 @@
|
||||
"version": "17.0.32",
|
||||
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz",
|
||||
"integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/yargs-parser": "*"
|
||||
@@ -3373,7 +4383,6 @@
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz",
|
||||
"integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/types": "^29.6.3",
|
||||
@@ -3391,7 +4400,6 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
|
||||
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
@@ -3401,7 +4409,6 @@
|
||||
"version": "26.6.3",
|
||||
"resolved": "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz",
|
||||
"integrity": "sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jest/console": "^26.6.2",
|
||||
"@jest/reporters": "^26.6.2",
|
||||
@@ -3440,7 +4447,6 @@
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz",
|
||||
"integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jest/types": "^26.6.2",
|
||||
"@types/node": "*",
|
||||
@@ -3457,7 +4463,6 @@
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz",
|
||||
"integrity": "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@bcoe/v8-coverage": "^0.2.3",
|
||||
"@jest/console": "^26.6.2",
|
||||
@@ -3495,7 +4500,6 @@
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz",
|
||||
"integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jest/console": "^26.6.2",
|
||||
"@jest/types": "^26.6.2",
|
||||
@@ -3510,7 +4514,6 @@
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz",
|
||||
"integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.7.5",
|
||||
"@istanbuljs/schema": "^0.1.2",
|
||||
@@ -3525,7 +4528,6 @@
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz",
|
||||
"integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.0.0",
|
||||
"@jest/types": "^26.6.2",
|
||||
@@ -3545,7 +4547,6 @@
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz",
|
||||
"integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*",
|
||||
"merge-stream": "^2.0.0",
|
||||
@@ -3559,7 +4560,6 @@
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz",
|
||||
"integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jest/types": "^26.6.2",
|
||||
"ansi-regex": "^5.0.0",
|
||||
@@ -3574,7 +4574,6 @@
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
||||
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"glob": "^7.1.3"
|
||||
},
|
||||
@@ -3589,7 +4588,6 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
|
||||
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -3598,7 +4596,6 @@
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
@@ -3607,7 +4604,6 @@
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz",
|
||||
"integrity": "sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/istanbul-lib-coverage": "^2.0.1",
|
||||
"convert-source-map": "^1.6.0",
|
||||
@@ -3621,7 +4617,6 @@
|
||||
"version": "0.7.4",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
|
||||
"integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
@@ -3640,10 +4635,23 @@
|
||||
"node": ">= 10.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@jest/expect": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz",
|
||||
"integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"expect": "^29.7.0",
|
||||
"jest-snapshot": "^29.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jest/expect-utils": {
|
||||
"version": "29.6.4",
|
||||
"resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.6.4.tgz",
|
||||
"integrity": "sha512-FEhkJhqtvBwgSpiTrocquJCdXPsyvNKcl/n7A3u7X4pVoF4bswm11c9d4AV+kfq2Gpv/mM8x7E7DsRvH+djkrg==",
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz",
|
||||
"integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==",
|
||||
"dependencies": {
|
||||
"jest-get-type": "^29.6.3"
|
||||
},
|
||||
@@ -3651,6 +4659,212 @@
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jest/expect/node_modules/@jest/transform": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz",
|
||||
"integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.11.6",
|
||||
"@jest/types": "^29.6.3",
|
||||
"@jridgewell/trace-mapping": "^0.3.18",
|
||||
"babel-plugin-istanbul": "^6.1.1",
|
||||
"chalk": "^4.0.0",
|
||||
"convert-source-map": "^2.0.0",
|
||||
"fast-json-stable-stringify": "^2.1.0",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"jest-haste-map": "^29.7.0",
|
||||
"jest-regex-util": "^29.6.3",
|
||||
"jest-util": "^29.7.0",
|
||||
"micromatch": "^4.0.4",
|
||||
"pirates": "^4.0.4",
|
||||
"slash": "^3.0.0",
|
||||
"write-file-atomic": "^4.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jest/expect/node_modules/@jest/types": {
|
||||
"version": "29.6.3",
|
||||
"resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
|
||||
"integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/schemas": "^29.6.3",
|
||||
"@types/istanbul-lib-coverage": "^2.0.0",
|
||||
"@types/istanbul-reports": "^3.0.0",
|
||||
"@types/node": "*",
|
||||
"@types/yargs": "^17.0.8",
|
||||
"chalk": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jest/expect/node_modules/@types/yargs": {
|
||||
"version": "17.0.32",
|
||||
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz",
|
||||
"integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/yargs-parser": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@jest/expect/node_modules/ansi-styles": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
|
||||
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@jest/expect/node_modules/convert-source-map": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
|
||||
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@jest/expect/node_modules/jest-haste-map": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz",
|
||||
"integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/types": "^29.6.3",
|
||||
"@types/graceful-fs": "^4.1.3",
|
||||
"@types/node": "*",
|
||||
"anymatch": "^3.0.3",
|
||||
"fb-watchman": "^2.0.0",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"jest-regex-util": "^29.6.3",
|
||||
"jest-util": "^29.7.0",
|
||||
"jest-worker": "^29.7.0",
|
||||
"micromatch": "^4.0.4",
|
||||
"walker": "^1.0.8"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "^2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@jest/expect/node_modules/jest-regex-util": {
|
||||
"version": "29.6.3",
|
||||
"resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz",
|
||||
"integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jest/expect/node_modules/jest-snapshot": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz",
|
||||
"integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.11.6",
|
||||
"@babel/generator": "^7.7.2",
|
||||
"@babel/plugin-syntax-jsx": "^7.7.2",
|
||||
"@babel/plugin-syntax-typescript": "^7.7.2",
|
||||
"@babel/types": "^7.3.3",
|
||||
"@jest/expect-utils": "^29.7.0",
|
||||
"@jest/transform": "^29.7.0",
|
||||
"@jest/types": "^29.6.3",
|
||||
"babel-preset-current-node-syntax": "^1.0.0",
|
||||
"chalk": "^4.0.0",
|
||||
"expect": "^29.7.0",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"jest-diff": "^29.7.0",
|
||||
"jest-get-type": "^29.6.3",
|
||||
"jest-matcher-utils": "^29.7.0",
|
||||
"jest-message-util": "^29.7.0",
|
||||
"jest-util": "^29.7.0",
|
||||
"natural-compare": "^1.4.0",
|
||||
"pretty-format": "^29.7.0",
|
||||
"semver": "^7.5.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jest/expect/node_modules/jest-util": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz",
|
||||
"integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/types": "^29.6.3",
|
||||
"@types/node": "*",
|
||||
"chalk": "^4.0.0",
|
||||
"ci-info": "^3.2.0",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"picomatch": "^2.2.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jest/expect/node_modules/pretty-format": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
|
||||
"integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/schemas": "^29.6.3",
|
||||
"ansi-styles": "^5.0.0",
|
||||
"react-is": "^18.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jest/expect/node_modules/react-is": {
|
||||
"version": "18.3.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
|
||||
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@jest/expect/node_modules/semver": {
|
||||
"version": "7.6.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
|
||||
"integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@jest/expect/node_modules/slash": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
|
||||
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@jest/expect/node_modules/write-file-atomic": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz",
|
||||
"integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"imurmurhash": "^0.1.4",
|
||||
"signal-exit": "^3.0.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jest/fake-timers": {
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz",
|
||||
@@ -3826,7 +5040,6 @@
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz",
|
||||
"integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@bcoe/v8-coverage": "^0.2.3",
|
||||
@@ -3870,7 +5083,6 @@
|
||||
"version": "7.24.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.3.tgz",
|
||||
"integrity": "sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@ampproject/remapping": "^2.2.0",
|
||||
@@ -3901,7 +5113,6 @@
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz",
|
||||
"integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.11.6",
|
||||
@@ -3928,7 +5139,6 @@
|
||||
"version": "29.6.3",
|
||||
"resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
|
||||
"integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/schemas": "^29.6.3",
|
||||
@@ -3946,7 +5156,6 @@
|
||||
"version": "17.0.32",
|
||||
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz",
|
||||
"integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/yargs-parser": "*"
|
||||
@@ -3956,14 +5165,12 @@
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
|
||||
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
|
||||
"dev": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@jest/reporters/node_modules/istanbul-lib-instrument": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.2.tgz",
|
||||
"integrity": "sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.23.9",
|
||||
@@ -3980,7 +5187,6 @@
|
||||
"version": "7.6.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
|
||||
"integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"lru-cache": "^6.0.0"
|
||||
@@ -3996,7 +5202,6 @@
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz",
|
||||
"integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/types": "^29.6.3",
|
||||
@@ -4022,7 +5227,6 @@
|
||||
"version": "29.6.3",
|
||||
"resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz",
|
||||
"integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
@@ -4032,7 +5236,6 @@
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz",
|
||||
"integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/types": "^29.6.3",
|
||||
@@ -4050,7 +5253,6 @@
|
||||
"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,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"yallist": "^4.0.0"
|
||||
@@ -4063,7 +5265,6 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
|
||||
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
@@ -4073,7 +5274,6 @@
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz",
|
||||
"integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"imurmurhash": "^0.1.4",
|
||||
@@ -4087,7 +5287,6 @@
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||
"dev": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@jest/schemas": {
|
||||
@@ -4126,7 +5325,6 @@
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz",
|
||||
"integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/console": "^29.7.0",
|
||||
@@ -4142,7 +5340,6 @@
|
||||
"version": "29.6.3",
|
||||
"resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
|
||||
"integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/schemas": "^29.6.3",
|
||||
@@ -4160,7 +5357,6 @@
|
||||
"version": "17.0.32",
|
||||
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz",
|
||||
"integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/yargs-parser": "*"
|
||||
@@ -4503,9 +5699,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build": {
|
||||
"version": "13.0.28",
|
||||
"resolved": "https://registry.npmjs.org/@openedx/frontend-build/-/frontend-build-13.0.28.tgz",
|
||||
"integrity": "sha512-9CSTpA7EGlC5lHaH03X3E1YpCp2SPsJ5It7905KimacGlliK0yf8FZIyluOCm3jSGQ5u/xjvZyw6xbl0XJCKZA==",
|
||||
"version": "13.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@openedx/frontend-build/-/frontend-build-13.1.4.tgz",
|
||||
"integrity": "sha512-YqXU6KgFnmDD/vGLvq/A9NP6R8lHfaEx64ajQC50ebFMlF3J7HWUruct4PuroeTupq9UAfRZUilzQHYQZjV08A==",
|
||||
"dependencies": {
|
||||
"@babel/cli": "7.22.5",
|
||||
"@babel/core": "7.22.5",
|
||||
@@ -4521,7 +5717,7 @@
|
||||
"@fullhuman/postcss-purgecss": "5.0.0",
|
||||
"@pmmmwh/react-refresh-webpack-plugin": "0.5.11",
|
||||
"@svgr/webpack": "8.1.0",
|
||||
"autoprefixer": "10.4.16",
|
||||
"autoprefixer": "10.4.19",
|
||||
"babel-jest": "26.6.3",
|
||||
"babel-loader": "9.1.3",
|
||||
"babel-plugin-formatjs": "^10.4.0",
|
||||
@@ -4535,19 +5731,20 @@
|
||||
"dotenv-webpack": "8.0.1",
|
||||
"eslint": "8.44.0",
|
||||
"eslint-config-airbnb": "19.0.4",
|
||||
"eslint-plugin-formatjs": "^4.12.2",
|
||||
"eslint-plugin-import": "2.27.5",
|
||||
"eslint-plugin-jsx-a11y": "6.7.1",
|
||||
"eslint-plugin-react": "7.32.2",
|
||||
"eslint-plugin-react-hooks": "4.6.0",
|
||||
"express": "4.18.2",
|
||||
"express": "^4.18.2",
|
||||
"file-loader": "6.2.0",
|
||||
"html-webpack-plugin": "5.6.0",
|
||||
"identity-obj-proxy": "3.0.0",
|
||||
"image-minimizer-webpack-plugin": "3.8.3",
|
||||
"jest": "26.6.3",
|
||||
"mini-css-extract-plugin": "1.6.2",
|
||||
"postcss": "8.4.33",
|
||||
"postcss-custom-media": "10.0.2",
|
||||
"postcss": "8.4.38",
|
||||
"postcss-custom-media": "10.0.4",
|
||||
"postcss-loader": "7.3.4",
|
||||
"postcss-rtlcss": "5.1.0",
|
||||
"react-dev-utils": "12.0.1",
|
||||
@@ -4559,11 +5756,11 @@
|
||||
"source-map-loader": "4.0.2",
|
||||
"style-loader": "3.3.4",
|
||||
"url-loader": "4.1.1",
|
||||
"webpack": "5.89.0",
|
||||
"webpack-bundle-analyzer": "4.10.1",
|
||||
"webpack-cli": "5.1.4",
|
||||
"webpack-dev-server": "4.15.1",
|
||||
"webpack-merge": "5.10.0"
|
||||
"webpack": "^5.89.0",
|
||||
"webpack-bundle-analyzer": "^4.10.1",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"webpack-dev-server": "^4.15.1",
|
||||
"webpack-merge": "^5.10.0"
|
||||
},
|
||||
"bin": {
|
||||
"fedx-scripts": "bin/fedx-scripts.js"
|
||||
@@ -4572,359 +5769,6 @@
|
||||
"react": "^16.9.0 || ^17.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/@jest/console": {
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz",
|
||||
"integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==",
|
||||
"dependencies": {
|
||||
"@jest/types": "^26.6.2",
|
||||
"@types/node": "*",
|
||||
"chalk": "^4.0.0",
|
||||
"jest-message-util": "^26.6.2",
|
||||
"jest-util": "^26.6.2",
|
||||
"slash": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/@jest/core": {
|
||||
"version": "26.6.3",
|
||||
"resolved": "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz",
|
||||
"integrity": "sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==",
|
||||
"dependencies": {
|
||||
"@jest/console": "^26.6.2",
|
||||
"@jest/reporters": "^26.6.2",
|
||||
"@jest/test-result": "^26.6.2",
|
||||
"@jest/transform": "^26.6.2",
|
||||
"@jest/types": "^26.6.2",
|
||||
"@types/node": "*",
|
||||
"ansi-escapes": "^4.2.1",
|
||||
"chalk": "^4.0.0",
|
||||
"exit": "^0.1.2",
|
||||
"graceful-fs": "^4.2.4",
|
||||
"jest-changed-files": "^26.6.2",
|
||||
"jest-config": "^26.6.3",
|
||||
"jest-haste-map": "^26.6.2",
|
||||
"jest-message-util": "^26.6.2",
|
||||
"jest-regex-util": "^26.0.0",
|
||||
"jest-resolve": "^26.6.2",
|
||||
"jest-resolve-dependencies": "^26.6.3",
|
||||
"jest-runner": "^26.6.3",
|
||||
"jest-runtime": "^26.6.3",
|
||||
"jest-snapshot": "^26.6.2",
|
||||
"jest-util": "^26.6.2",
|
||||
"jest-validate": "^26.6.2",
|
||||
"jest-watcher": "^26.6.2",
|
||||
"micromatch": "^4.0.2",
|
||||
"p-each-series": "^2.1.0",
|
||||
"rimraf": "^3.0.0",
|
||||
"slash": "^3.0.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/@jest/environment": {
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz",
|
||||
"integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==",
|
||||
"dependencies": {
|
||||
"@jest/fake-timers": "^26.6.2",
|
||||
"@jest/types": "^26.6.2",
|
||||
"@types/node": "*",
|
||||
"jest-mock": "^26.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/@jest/fake-timers": {
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz",
|
||||
"integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==",
|
||||
"dependencies": {
|
||||
"@jest/types": "^26.6.2",
|
||||
"@sinonjs/fake-timers": "^6.0.1",
|
||||
"@types/node": "*",
|
||||
"jest-message-util": "^26.6.2",
|
||||
"jest-mock": "^26.6.2",
|
||||
"jest-util": "^26.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/@jest/globals": {
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz",
|
||||
"integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==",
|
||||
"dependencies": {
|
||||
"@jest/environment": "^26.6.2",
|
||||
"@jest/types": "^26.6.2",
|
||||
"expect": "^26.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/@jest/reporters": {
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz",
|
||||
"integrity": "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==",
|
||||
"dependencies": {
|
||||
"@bcoe/v8-coverage": "^0.2.3",
|
||||
"@jest/console": "^26.6.2",
|
||||
"@jest/test-result": "^26.6.2",
|
||||
"@jest/transform": "^26.6.2",
|
||||
"@jest/types": "^26.6.2",
|
||||
"chalk": "^4.0.0",
|
||||
"collect-v8-coverage": "^1.0.0",
|
||||
"exit": "^0.1.2",
|
||||
"glob": "^7.1.2",
|
||||
"graceful-fs": "^4.2.4",
|
||||
"istanbul-lib-coverage": "^3.0.0",
|
||||
"istanbul-lib-instrument": "^4.0.3",
|
||||
"istanbul-lib-report": "^3.0.0",
|
||||
"istanbul-lib-source-maps": "^4.0.0",
|
||||
"istanbul-reports": "^3.0.2",
|
||||
"jest-haste-map": "^26.6.2",
|
||||
"jest-resolve": "^26.6.2",
|
||||
"jest-util": "^26.6.2",
|
||||
"jest-worker": "^26.6.2",
|
||||
"slash": "^3.0.0",
|
||||
"source-map": "^0.6.0",
|
||||
"string-length": "^4.0.1",
|
||||
"terminal-link": "^2.0.0",
|
||||
"v8-to-istanbul": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.14.2"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"node-notifier": "^8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/@jest/source-map": {
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz",
|
||||
"integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==",
|
||||
"dependencies": {
|
||||
"callsites": "^3.0.0",
|
||||
"graceful-fs": "^4.2.4",
|
||||
"source-map": "^0.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/@jest/test-result": {
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz",
|
||||
"integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==",
|
||||
"dependencies": {
|
||||
"@jest/console": "^26.6.2",
|
||||
"@jest/types": "^26.6.2",
|
||||
"@types/istanbul-lib-coverage": "^2.0.0",
|
||||
"collect-v8-coverage": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/@jest/test-sequencer": {
|
||||
"version": "26.6.3",
|
||||
"resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz",
|
||||
"integrity": "sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==",
|
||||
"dependencies": {
|
||||
"@jest/test-result": "^26.6.2",
|
||||
"graceful-fs": "^4.2.4",
|
||||
"jest-haste-map": "^26.6.2",
|
||||
"jest-runner": "^26.6.3",
|
||||
"jest-runtime": "^26.6.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/@sinonjs/commons": {
|
||||
"version": "1.8.6",
|
||||
"resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz",
|
||||
"integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==",
|
||||
"dependencies": {
|
||||
"type-detect": "4.0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/@sinonjs/fake-timers": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz",
|
||||
"integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==",
|
||||
"dependencies": {
|
||||
"@sinonjs/commons": "^1.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/cjs-module-lexer": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz",
|
||||
"integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw=="
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/cliui": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
|
||||
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
|
||||
"dependencies": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"wrap-ansi": "^6.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/cssnano": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.0.3.tgz",
|
||||
"integrity": "sha512-MRq4CIj8pnyZpcI2qs6wswoYoDD1t0aL28n+41c1Ukcpm56m1h6mCexIHBGjfZfnTqtGSSCP4/fB1ovxgjBOiw==",
|
||||
"dependencies": {
|
||||
"cssnano-preset-default": "^6.0.3",
|
||||
"lilconfig": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14 || ^16 || >=18.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/cssnano"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.31"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/diff-sequences": {
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz",
|
||||
"integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==",
|
||||
"engines": {
|
||||
"node": ">= 10.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/emittery": {
|
||||
"version": "0.7.2",
|
||||
"resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz",
|
||||
"integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sindresorhus/emittery?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/execa": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz",
|
||||
"integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==",
|
||||
"dependencies": {
|
||||
"cross-spawn": "^7.0.0",
|
||||
"get-stream": "^5.0.0",
|
||||
"human-signals": "^1.1.1",
|
||||
"is-stream": "^2.0.0",
|
||||
"merge-stream": "^2.0.0",
|
||||
"npm-run-path": "^4.0.0",
|
||||
"onetime": "^5.1.0",
|
||||
"signal-exit": "^3.0.2",
|
||||
"strip-final-newline": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sindresorhus/execa?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/expect": {
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz",
|
||||
"integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==",
|
||||
"dependencies": {
|
||||
"@jest/types": "^26.6.2",
|
||||
"ansi-styles": "^4.0.0",
|
||||
"jest-get-type": "^26.3.0",
|
||||
"jest-matcher-utils": "^26.6.2",
|
||||
"jest-message-util": "^26.6.2",
|
||||
"jest-regex-util": "^26.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/find-up": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
|
||||
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
|
||||
"dependencies": {
|
||||
"locate-path": "^5.0.0",
|
||||
"path-exists": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/get-stream": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
|
||||
"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
|
||||
"dependencies": {
|
||||
"pump": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/html-webpack-plugin": {
|
||||
"version": "5.6.0",
|
||||
"resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz",
|
||||
"integrity": "sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==",
|
||||
"dependencies": {
|
||||
"@types/html-minifier-terser": "^6.0.0",
|
||||
"html-minifier-terser": "^6.0.2",
|
||||
"lodash": "^4.17.21",
|
||||
"pretty-error": "^4.0.0",
|
||||
"tapable": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/html-webpack-plugin"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@rspack/core": "0.x || 1.x",
|
||||
"webpack": "^5.20.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@rspack/core": {
|
||||
"optional": true
|
||||
},
|
||||
"webpack": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/human-signals": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
|
||||
"integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==",
|
||||
"engines": {
|
||||
"node": ">=8.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/iconv-lite": {
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
||||
@@ -4936,434 +5780,6 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/istanbul-lib-instrument": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz",
|
||||
"integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.7.5",
|
||||
"@istanbuljs/schema": "^0.1.2",
|
||||
"istanbul-lib-coverage": "^3.0.0",
|
||||
"semver": "^6.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/jest": {
|
||||
"version": "26.6.3",
|
||||
"resolved": "https://registry.npmjs.org/jest/-/jest-26.6.3.tgz",
|
||||
"integrity": "sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==",
|
||||
"dependencies": {
|
||||
"@jest/core": "^26.6.3",
|
||||
"import-local": "^3.0.2",
|
||||
"jest-cli": "^26.6.3"
|
||||
},
|
||||
"bin": {
|
||||
"jest": "bin/jest.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/jest-changed-files": {
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.6.2.tgz",
|
||||
"integrity": "sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==",
|
||||
"dependencies": {
|
||||
"@jest/types": "^26.6.2",
|
||||
"execa": "^4.0.0",
|
||||
"throat": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/jest-cli": {
|
||||
"version": "26.6.3",
|
||||
"resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz",
|
||||
"integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==",
|
||||
"dependencies": {
|
||||
"@jest/core": "^26.6.3",
|
||||
"@jest/test-result": "^26.6.2",
|
||||
"@jest/types": "^26.6.2",
|
||||
"chalk": "^4.0.0",
|
||||
"exit": "^0.1.2",
|
||||
"graceful-fs": "^4.2.4",
|
||||
"import-local": "^3.0.2",
|
||||
"is-ci": "^2.0.0",
|
||||
"jest-config": "^26.6.3",
|
||||
"jest-util": "^26.6.2",
|
||||
"jest-validate": "^26.6.2",
|
||||
"prompts": "^2.0.1",
|
||||
"yargs": "^15.4.1"
|
||||
},
|
||||
"bin": {
|
||||
"jest": "bin/jest.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/jest-config": {
|
||||
"version": "26.6.3",
|
||||
"resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz",
|
||||
"integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.1.0",
|
||||
"@jest/test-sequencer": "^26.6.3",
|
||||
"@jest/types": "^26.6.2",
|
||||
"babel-jest": "^26.6.3",
|
||||
"chalk": "^4.0.0",
|
||||
"deepmerge": "^4.2.2",
|
||||
"glob": "^7.1.1",
|
||||
"graceful-fs": "^4.2.4",
|
||||
"jest-environment-jsdom": "^26.6.2",
|
||||
"jest-environment-node": "^26.6.2",
|
||||
"jest-get-type": "^26.3.0",
|
||||
"jest-jasmine2": "^26.6.3",
|
||||
"jest-regex-util": "^26.0.0",
|
||||
"jest-resolve": "^26.6.2",
|
||||
"jest-util": "^26.6.2",
|
||||
"jest-validate": "^26.6.2",
|
||||
"micromatch": "^4.0.2",
|
||||
"pretty-format": "^26.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.14.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"ts-node": ">=9.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"ts-node": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/jest-diff": {
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz",
|
||||
"integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==",
|
||||
"dependencies": {
|
||||
"chalk": "^4.0.0",
|
||||
"diff-sequences": "^26.6.2",
|
||||
"jest-get-type": "^26.3.0",
|
||||
"pretty-format": "^26.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/jest-docblock": {
|
||||
"version": "26.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz",
|
||||
"integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==",
|
||||
"dependencies": {
|
||||
"detect-newline": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/jest-environment-node": {
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz",
|
||||
"integrity": "sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==",
|
||||
"dependencies": {
|
||||
"@jest/environment": "^26.6.2",
|
||||
"@jest/fake-timers": "^26.6.2",
|
||||
"@jest/types": "^26.6.2",
|
||||
"@types/node": "*",
|
||||
"jest-mock": "^26.6.2",
|
||||
"jest-util": "^26.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/jest-get-type": {
|
||||
"version": "26.3.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz",
|
||||
"integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==",
|
||||
"engines": {
|
||||
"node": ">= 10.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/jest-leak-detector": {
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz",
|
||||
"integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==",
|
||||
"dependencies": {
|
||||
"jest-get-type": "^26.3.0",
|
||||
"pretty-format": "^26.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/jest-matcher-utils": {
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz",
|
||||
"integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==",
|
||||
"dependencies": {
|
||||
"chalk": "^4.0.0",
|
||||
"jest-diff": "^26.6.2",
|
||||
"jest-get-type": "^26.3.0",
|
||||
"pretty-format": "^26.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/jest-message-util": {
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz",
|
||||
"integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==",
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.0.0",
|
||||
"@jest/types": "^26.6.2",
|
||||
"@types/stack-utils": "^2.0.0",
|
||||
"chalk": "^4.0.0",
|
||||
"graceful-fs": "^4.2.4",
|
||||
"micromatch": "^4.0.2",
|
||||
"pretty-format": "^26.6.2",
|
||||
"slash": "^3.0.0",
|
||||
"stack-utils": "^2.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/jest-mock": {
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz",
|
||||
"integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==",
|
||||
"dependencies": {
|
||||
"@jest/types": "^26.6.2",
|
||||
"@types/node": "*"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/jest-resolve": {
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz",
|
||||
"integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==",
|
||||
"dependencies": {
|
||||
"@jest/types": "^26.6.2",
|
||||
"chalk": "^4.0.0",
|
||||
"graceful-fs": "^4.2.4",
|
||||
"jest-pnp-resolver": "^1.2.2",
|
||||
"jest-util": "^26.6.2",
|
||||
"read-pkg-up": "^7.0.1",
|
||||
"resolve": "^1.18.1",
|
||||
"slash": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/jest-resolve-dependencies": {
|
||||
"version": "26.6.3",
|
||||
"resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz",
|
||||
"integrity": "sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg==",
|
||||
"dependencies": {
|
||||
"@jest/types": "^26.6.2",
|
||||
"jest-regex-util": "^26.0.0",
|
||||
"jest-snapshot": "^26.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/jest-runner": {
|
||||
"version": "26.6.3",
|
||||
"resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz",
|
||||
"integrity": "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==",
|
||||
"dependencies": {
|
||||
"@jest/console": "^26.6.2",
|
||||
"@jest/environment": "^26.6.2",
|
||||
"@jest/test-result": "^26.6.2",
|
||||
"@jest/types": "^26.6.2",
|
||||
"@types/node": "*",
|
||||
"chalk": "^4.0.0",
|
||||
"emittery": "^0.7.1",
|
||||
"exit": "^0.1.2",
|
||||
"graceful-fs": "^4.2.4",
|
||||
"jest-config": "^26.6.3",
|
||||
"jest-docblock": "^26.0.0",
|
||||
"jest-haste-map": "^26.6.2",
|
||||
"jest-leak-detector": "^26.6.2",
|
||||
"jest-message-util": "^26.6.2",
|
||||
"jest-resolve": "^26.6.2",
|
||||
"jest-runtime": "^26.6.3",
|
||||
"jest-util": "^26.6.2",
|
||||
"jest-worker": "^26.6.2",
|
||||
"source-map-support": "^0.5.6",
|
||||
"throat": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/jest-runtime": {
|
||||
"version": "26.6.3",
|
||||
"resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz",
|
||||
"integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==",
|
||||
"dependencies": {
|
||||
"@jest/console": "^26.6.2",
|
||||
"@jest/environment": "^26.6.2",
|
||||
"@jest/fake-timers": "^26.6.2",
|
||||
"@jest/globals": "^26.6.2",
|
||||
"@jest/source-map": "^26.6.2",
|
||||
"@jest/test-result": "^26.6.2",
|
||||
"@jest/transform": "^26.6.2",
|
||||
"@jest/types": "^26.6.2",
|
||||
"@types/yargs": "^15.0.0",
|
||||
"chalk": "^4.0.0",
|
||||
"cjs-module-lexer": "^0.6.0",
|
||||
"collect-v8-coverage": "^1.0.0",
|
||||
"exit": "^0.1.2",
|
||||
"glob": "^7.1.3",
|
||||
"graceful-fs": "^4.2.4",
|
||||
"jest-config": "^26.6.3",
|
||||
"jest-haste-map": "^26.6.2",
|
||||
"jest-message-util": "^26.6.2",
|
||||
"jest-mock": "^26.6.2",
|
||||
"jest-regex-util": "^26.0.0",
|
||||
"jest-resolve": "^26.6.2",
|
||||
"jest-snapshot": "^26.6.2",
|
||||
"jest-util": "^26.6.2",
|
||||
"jest-validate": "^26.6.2",
|
||||
"slash": "^3.0.0",
|
||||
"strip-bom": "^4.0.0",
|
||||
"yargs": "^15.4.1"
|
||||
},
|
||||
"bin": {
|
||||
"jest-runtime": "bin/jest-runtime.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/jest-snapshot": {
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz",
|
||||
"integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==",
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.0.0",
|
||||
"@jest/types": "^26.6.2",
|
||||
"@types/babel__traverse": "^7.0.4",
|
||||
"@types/prettier": "^2.0.0",
|
||||
"chalk": "^4.0.0",
|
||||
"expect": "^26.6.2",
|
||||
"graceful-fs": "^4.2.4",
|
||||
"jest-diff": "^26.6.2",
|
||||
"jest-get-type": "^26.3.0",
|
||||
"jest-haste-map": "^26.6.2",
|
||||
"jest-matcher-utils": "^26.6.2",
|
||||
"jest-message-util": "^26.6.2",
|
||||
"jest-resolve": "^26.6.2",
|
||||
"natural-compare": "^1.4.0",
|
||||
"pretty-format": "^26.6.2",
|
||||
"semver": "^7.3.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/jest-snapshot/node_modules/semver": {
|
||||
"version": "7.6.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
|
||||
"integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
|
||||
"dependencies": {
|
||||
"lru-cache": "^6.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/jest-validate": {
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz",
|
||||
"integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==",
|
||||
"dependencies": {
|
||||
"@jest/types": "^26.6.2",
|
||||
"camelcase": "^6.0.0",
|
||||
"chalk": "^4.0.0",
|
||||
"jest-get-type": "^26.3.0",
|
||||
"leven": "^3.1.0",
|
||||
"pretty-format": "^26.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/jest-watcher": {
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz",
|
||||
"integrity": "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==",
|
||||
"dependencies": {
|
||||
"@jest/test-result": "^26.6.2",
|
||||
"@jest/types": "^26.6.2",
|
||||
"@types/node": "*",
|
||||
"ansi-escapes": "^4.2.1",
|
||||
"chalk": "^4.0.0",
|
||||
"jest-util": "^26.6.2",
|
||||
"string-length": "^4.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/jest-worker": {
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz",
|
||||
"integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==",
|
||||
"dependencies": {
|
||||
"@types/node": "*",
|
||||
"merge-stream": "^2.0.0",
|
||||
"supports-color": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/lilconfig": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz",
|
||||
"integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antonk52"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/locate-path": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
|
||||
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
|
||||
"dependencies": {
|
||||
"p-locate": "^4.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
@@ -5375,58 +5791,6 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/p-limit": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
|
||||
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
|
||||
"dependencies": {
|
||||
"p-try": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/p-locate": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
|
||||
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
|
||||
"dependencies": {
|
||||
"p-limit": "^2.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/postcss": {
|
||||
"version": "8.4.33",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.33.tgz",
|
||||
"integrity": "sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/postcss/"
|
||||
},
|
||||
{
|
||||
"type": "tidelift",
|
||||
"url": "https://tidelift.com/funding/github/npm/postcss"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"nanoid": "^3.3.7",
|
||||
"picocolors": "^1.0.0",
|
||||
"source-map-js": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || >=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/postcss-loader": {
|
||||
"version": "7.3.4",
|
||||
"resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.4.tgz",
|
||||
@@ -5448,62 +5812,6 @@
|
||||
"webpack": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/postcss-loader/node_modules/semver": {
|
||||
"version": "7.6.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
|
||||
"integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
|
||||
"dependencies": {
|
||||
"lru-cache": "^6.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/postcss-rtlcss": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-rtlcss/-/postcss-rtlcss-5.1.0.tgz",
|
||||
"integrity": "sha512-FjZ8HPwr6dWR1Jzzz+TZqkEhkfLiR7sKgsHTDqrYGd51KtZdaDpdJ5aqHmqWoXZsSyJgBIkwZPt5JoEPvkX3Nw==",
|
||||
"dependencies": {
|
||||
"rtlcss": "4.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.21"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/pretty-format": {
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz",
|
||||
"integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==",
|
||||
"dependencies": {
|
||||
"@jest/types": "^26.6.2",
|
||||
"ansi-regex": "^5.0.0",
|
||||
"ansi-styles": "^4.0.0",
|
||||
"react-is": "^17.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/rimraf": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
||||
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
|
||||
"dependencies": {
|
||||
"glob": "^7.1.3"
|
||||
},
|
||||
"bin": {
|
||||
"rimraf": "bin.js"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/sass": {
|
||||
"version": "1.69.7",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.69.7.tgz",
|
||||
@@ -5556,20 +5864,18 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/slash": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
|
||||
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
|
||||
"node_modules/@openedx/frontend-build/node_modules/semver": {
|
||||
"version": "7.6.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
|
||||
"integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
|
||||
"dependencies": {
|
||||
"lru-cache": "^6.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/source-map-loader": {
|
||||
@@ -5591,377 +5897,30 @@
|
||||
"webpack": "^5.72.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/string-width": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/v8-to-istanbul": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz",
|
||||
"integrity": "sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow==",
|
||||
"dependencies": {
|
||||
"@types/istanbul-lib-coverage": "^2.0.1",
|
||||
"convert-source-map": "^1.6.0",
|
||||
"source-map": "^0.7.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/v8-to-istanbul/node_modules/source-map": {
|
||||
"version": "0.7.4",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
|
||||
"integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/webpack-merge": {
|
||||
"version": "5.10.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz",
|
||||
"integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==",
|
||||
"dependencies": {
|
||||
"clone-deep": "^4.0.1",
|
||||
"flat": "^5.0.2",
|
||||
"wildcard": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/y18n": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
|
||||
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/yargs": {
|
||||
"version": "15.4.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
|
||||
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
|
||||
"dependencies": {
|
||||
"cliui": "^6.0.0",
|
||||
"decamelize": "^1.2.0",
|
||||
"find-up": "^4.1.0",
|
||||
"get-caller-file": "^2.0.1",
|
||||
"require-directory": "^2.1.1",
|
||||
"require-main-filename": "^2.0.0",
|
||||
"set-blocking": "^2.0.0",
|
||||
"string-width": "^4.2.0",
|
||||
"which-module": "^2.0.0",
|
||||
"y18n": "^4.0.0",
|
||||
"yargs-parser": "^18.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/yargs-parser": {
|
||||
"version": "18.1.3",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
|
||||
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
|
||||
"dependencies": {
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/yargs-parser/node_modules/camelcase": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
|
||||
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@openedx/frontend-plugin-framework/-/frontend-plugin-framework-1.0.2.tgz",
|
||||
"integrity": "sha512-9KVFtVp14foXuZVzIN7EyXMha9fhbu4SwXBle81HFzuHEpm46+qxtiIOktH6b4TYh74SMzuSphgP30MCHr1P8Q==",
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@openedx/frontend-plugin-framework/-/frontend-plugin-framework-1.1.2.tgz",
|
||||
"integrity": "sha512-DzhkZTbmxX09xXE6yyWs9xSq40cO+CgFF80nq1M7pJAeY0mtv7TWlQT8/YnhmjHS3Kj1u9GdqpRpYu8vHuRurA==",
|
||||
"dependencies": {
|
||||
"@edx/brand": "npm:@openedx/brand-openedx@^1.2.2",
|
||||
"@edx/frontend-component-footer": "13.0.3",
|
||||
"@edx/frontend-component-header": "5.0.2",
|
||||
"@edx/frontend-platform": "^7.1.0",
|
||||
"@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.2.0",
|
||||
"@openedx/paragon": "^21.0.0",
|
||||
"classnames": "^2.3.2",
|
||||
"core-js": "3.36.0",
|
||||
"prop-types": "15.8.1",
|
||||
"react": "17.0.2",
|
||||
"react-dom": "17.0.2",
|
||||
"react-error-boundary": "^4.0.11",
|
||||
"react-redux": "7.2.9",
|
||||
"react-router": "6.22.2",
|
||||
"react-router-dom": "6.22.2",
|
||||
"redux": "4.2.1",
|
||||
"regenerator-runtime": "0.14.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework/node_modules/@edx/frontend-component-footer": {
|
||||
"version": "13.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-component-footer/-/frontend-component-footer-13.0.3.tgz",
|
||||
"integrity": "sha512-09vX6qC7AcDwG02qhBzKr4x58hpe9FXZrA9ui2cJnsG53pKaNL+wvOSRtDUBNexCf+y/iPg+8RgR+4alkzhZhw==",
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "6.5.1",
|
||||
"@fortawesome/free-brands-svg-icons": "6.5.1",
|
||||
"@fortawesome/free-regular-svg-icons": "6.5.1",
|
||||
"@fortawesome/free-solid-svg-icons": "6.5.1",
|
||||
"@fortawesome/react-fontawesome": "0.2.0",
|
||||
"lodash": "^4.17.21"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@edx/frontend-platform": "^7.0.0",
|
||||
"@openedx/paragon": ">= 21.11.3 < 23.0.0",
|
||||
"prop-types": "^15.5.10",
|
||||
"react": "^16.9.0 || ^17.0.0",
|
||||
"react-dom": "^16.9.0 || ^17.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework/node_modules/@edx/frontend-component-footer/node_modules/@fortawesome/fontawesome-common-types": {
|
||||
"version": "6.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.1.tgz",
|
||||
"integrity": "sha512-GkWzv+L6d2bI5f/Vk6ikJ9xtl7dfXtoRu3YGE6nq0p/FFqA1ebMOAWg3XgRyb0I6LYyYkiAo+3/KrwuBp8xG7A==",
|
||||
"hasInstallScript": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework/node_modules/@edx/frontend-component-footer/node_modules/@fortawesome/fontawesome-svg-core": {
|
||||
"version": "6.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.5.1.tgz",
|
||||
"integrity": "sha512-MfRCYlQPXoLlpem+egxjfkEuP9UQswTrlCOsknus/NcMoblTH2g0jPrapbcIb04KGA7E2GZxbAccGZfWoYgsrQ==",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-common-types": "6.5.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework/node_modules/@edx/frontend-component-footer/node_modules/@fortawesome/free-brands-svg-icons": {
|
||||
"version": "6.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.5.1.tgz",
|
||||
"integrity": "sha512-093l7DAkx0aEtBq66Sf19MgoZewv1zeY9/4C7vSKPO4qMwEsW/2VYTUTpBtLwfb9T2R73tXaRDPmE4UqLCYHfg==",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-common-types": "6.5.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework/node_modules/@edx/frontend-component-footer/node_modules/@fortawesome/free-regular-svg-icons": {
|
||||
"version": "6.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.5.1.tgz",
|
||||
"integrity": "sha512-m6ShXn+wvqEU69wSP84coxLbNl7sGVZb+Ca+XZq6k30SzuP3X4TfPqtycgUh9ASwlNh5OfQCd8pDIWxl+O+LlQ==",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-common-types": "6.5.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework/node_modules/@edx/frontend-component-footer/node_modules/@fortawesome/free-solid-svg-icons": {
|
||||
"version": "6.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.5.1.tgz",
|
||||
"integrity": "sha512-S1PPfU3mIJa59biTtXJz1oI0+KAXW6bkAb31XKhxdxtuXDiUIFsih4JR1v5BbxY7hVHsD1RKq+jRkVRaf773NQ==",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-common-types": "6.5.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework/node_modules/@fortawesome/fontawesome-common-types": {
|
||||
"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==",
|
||||
"hasInstallScript": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework/node_modules/@fortawesome/fontawesome-svg-core": {
|
||||
"version": "1.2.36",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.36.tgz",
|
||||
"integrity": "sha512-YUcsLQKYb6DmaJjIHdDWpBIGCcyE/W+p/LMGvjQem55Mm2XWVAP5kWTMKWLv9lwpCVjpLxPyOMOyUocP1GxrtA==",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-common-types": "^0.2.36"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework/node_modules/@fortawesome/react-fontawesome": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.0.tgz",
|
||||
"integrity": "sha512-uHg75Rb/XORTtVt7OS9WoK8uM276Ufi7gCzshVWkUJbHhh3svsUUeqXerrM96Wm7fRiDzfKRwSoahhMIkGAYHw==",
|
||||
"dependencies": {
|
||||
"prop-types": "^15.8.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "~1 || ~6",
|
||||
"react": ">=16.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework/node_modules/@openedx/paragon": {
|
||||
"version": "21.13.1",
|
||||
"resolved": "https://registry.npmjs.org/@openedx/paragon/-/paragon-21.13.1.tgz",
|
||||
"integrity": "sha512-sLL+Z3ZWIRM6x+OrKZV0S7/SQpEcSeRcDm7E3FzhsnAWudsJCTELvSW+84uy/8dwV7mJhttsBPqQEtNafbCyYA==",
|
||||
"workspaces": [
|
||||
"example",
|
||||
"component-generator",
|
||||
"www",
|
||||
"icons",
|
||||
"dependent-usage-analyzer"
|
||||
],
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "^6.1.1",
|
||||
"@fortawesome/react-fontawesome": "^0.1.18",
|
||||
"@popperjs/core": "^2.11.4",
|
||||
"bootstrap": "^4.6.2",
|
||||
"chalk": "^4.1.2",
|
||||
"child_process": "^1.0.2",
|
||||
"classnames": "^2.3.1",
|
||||
"email-prop-type": "^3.0.0",
|
||||
"file-selector": "^0.6.0",
|
||||
"font-awesome": "^4.7.0",
|
||||
"glob": "^8.0.3",
|
||||
"inquirer": "^8.2.5",
|
||||
"lodash.uniqby": "^4.7.0",
|
||||
"mailto-link": "^2.0.0",
|
||||
"prop-types": "^15.8.1",
|
||||
"react-bootstrap": "^1.6.5",
|
||||
"react-colorful": "^5.6.1",
|
||||
"react-dropzone": "^14.2.1",
|
||||
"react-focus-on": "^3.5.4",
|
||||
"react-imask": "^7.1.3",
|
||||
"react-loading-skeleton": "^3.1.0",
|
||||
"react-popper": "^2.2.5",
|
||||
"react-proptype-conditional-require": "^1.0.4",
|
||||
"react-responsive": "^8.2.0",
|
||||
"react-table": "^7.7.0",
|
||||
"react-transition-group": "^4.4.2",
|
||||
"tabbable": "^5.3.3",
|
||||
"uncontrollable": "^7.2.1",
|
||||
"uuid": "^9.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"paragon": "bin/paragon-scripts.js"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.8.6 || ^17.0.0",
|
||||
"react-dom": "^16.8.6 || ^17.0.0",
|
||||
"react-intl": "^5.25.1 || ^6.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework/node_modules/@openedx/paragon/node_modules/@fortawesome/fontawesome-common-types": {
|
||||
"version": "6.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.1.tgz",
|
||||
"integrity": "sha512-GkWzv+L6d2bI5f/Vk6ikJ9xtl7dfXtoRu3YGE6nq0p/FFqA1ebMOAWg3XgRyb0I6LYyYkiAo+3/KrwuBp8xG7A==",
|
||||
"hasInstallScript": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework/node_modules/@openedx/paragon/node_modules/@fortawesome/fontawesome-svg-core": {
|
||||
"version": "6.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.5.1.tgz",
|
||||
"integrity": "sha512-MfRCYlQPXoLlpem+egxjfkEuP9UQswTrlCOsknus/NcMoblTH2g0jPrapbcIb04KGA7E2GZxbAccGZfWoYgsrQ==",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-common-types": "6.5.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework/node_modules/@openedx/paragon/node_modules/@fortawesome/react-fontawesome": {
|
||||
"version": "0.1.19",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.19.tgz",
|
||||
"integrity": "sha512-Hyb+lB8T18cvLNX0S3llz7PcSOAJMLwiVKBuuzwM/nI5uoBw+gQjnf9il0fR1C3DKOI5Kc79pkJ4/xB0Uw9aFQ==",
|
||||
"dependencies": {
|
||||
"prop-types": "^15.8.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "~1 || ~6",
|
||||
"react": ">=16.x"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework/node_modules/@openedx/paragon/node_modules/glob": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
|
||||
"integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^5.0.1",
|
||||
"once": "^1.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework/node_modules/@remix-run/router": {
|
||||
"version": "1.15.2",
|
||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.2.tgz",
|
||||
"integrity": "sha512-+Rnav+CaoTE5QJc4Jcwh5toUpnVLKYbpU6Ys0zqbakqbaLQHeglLVHPfxOiQqdNmUy5C2lXz5dwC6tQNX2JW2Q==",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework/node_modules/brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework/node_modules/cli-cursor": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
|
||||
"integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
|
||||
"dependencies": {
|
||||
"restore-cursor": "^3.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework/node_modules/cli-width": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz",
|
||||
"integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==",
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
"@edx/frontend-platform": "^7.0.0 || ^8.0.0",
|
||||
"@openedx/paragon": "^21.0.0 || ^22.0.0",
|
||||
"prop-types": "^15.8.0",
|
||||
"react": "^17.0.0",
|
||||
"react-dom": "^17.0.0",
|
||||
"react-error-boundary": "^4.0.11"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework/node_modules/core-js": {
|
||||
@@ -5974,123 +5933,6 @@
|
||||
"url": "https://opencollective.com/core-js"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework/node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework/node_modules/escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework/node_modules/figures": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
|
||||
"integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==",
|
||||
"dependencies": {
|
||||
"escape-string-regexp": "^1.0.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework/node_modules/inquirer": {
|
||||
"version": "8.2.6",
|
||||
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.6.tgz",
|
||||
"integrity": "sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==",
|
||||
"dependencies": {
|
||||
"ansi-escapes": "^4.2.1",
|
||||
"chalk": "^4.1.1",
|
||||
"cli-cursor": "^3.1.0",
|
||||
"cli-width": "^3.0.0",
|
||||
"external-editor": "^3.0.3",
|
||||
"figures": "^3.0.0",
|
||||
"lodash": "^4.17.21",
|
||||
"mute-stream": "0.0.8",
|
||||
"ora": "^5.4.1",
|
||||
"run-async": "^2.4.0",
|
||||
"rxjs": "^7.5.5",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"through": "^2.3.6",
|
||||
"wrap-ansi": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework/node_modules/is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework/node_modules/minimatch": {
|
||||
"version": "5.1.6",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
|
||||
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework/node_modules/mute-stream": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
|
||||
"integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA=="
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework/node_modules/react-error-boundary": {
|
||||
"version": "4.0.13",
|
||||
"resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-4.0.13.tgz",
|
||||
"integrity": "sha512-b6PwbdSv8XeOSYvjt8LpgpKrZ0yGdtZokYwkwV2wlcZbxgopHX/hgPl5VgpnoVOWd868n1hktM8Qm4b+02MiLQ==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.12.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.13.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework/node_modules/react-router": {
|
||||
"version": "6.22.2",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.2.tgz",
|
||||
"integrity": "sha512-YD3Dzprzpcq+tBMHBS822tCjnWD3iIZbTeSXMY9LPSG541EfoBGyZ3bS25KEnaZjLcmQpw2AVLkFyfgXY8uvcw==",
|
||||
"dependencies": {
|
||||
"@remix-run/router": "1.15.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework/node_modules/react-router-dom": {
|
||||
"version": "6.22.2",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.22.2.tgz",
|
||||
"integrity": "sha512-WgqxD2qySEIBPZ3w0sHH+PUAiamDeszls9tzqMPBDA1YYVucTBXLU7+gtRfcSnhe92A3glPnvSxK2dhNoAVOIQ==",
|
||||
"dependencies": {
|
||||
"@remix-run/router": "1.15.2",
|
||||
"react-router": "6.22.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8",
|
||||
"react-dom": ">=16.8"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework/node_modules/redux": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
|
||||
@@ -6104,50 +5946,22 @@
|
||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
|
||||
"integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework/node_modules/restore-cursor": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
|
||||
"integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
|
||||
"node_modules/@openedx/frontend-slot-footer": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@openedx/frontend-slot-footer/-/frontend-slot-footer-1.0.2.tgz",
|
||||
"integrity": "sha512-Wmx/Das4wr3jYQ1/wk9ctYcM9ztfpY5fm6d5UKFSnKK1DbUbjliaPC3mdGR4wVRnH4MAf1OnNGZ8oj/bTDPGHg==",
|
||||
"dependencies": {
|
||||
"onetime": "^5.1.0",
|
||||
"signal-exit": "^3.0.2"
|
||||
"@openedx/frontend-plugin-framework": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework/node_modules/rxjs": {
|
||||
"version": "7.8.1",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
|
||||
"integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-plugin-framework/node_modules/string-width": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
"peerDependencies": {
|
||||
"@edx/frontend-component-footer": "*",
|
||||
"react": "^17.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/paragon": {
|
||||
"version": "22.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@openedx/paragon/-/paragon-22.1.1.tgz",
|
||||
"integrity": "sha512-XPRuV9zn7BeCIYfU5kE2XZ4YevjA0wfS/fuydB8Ta/aNY1dw9fQ7CjHOIfkZqDic4Jygusj/uhE/1WYJD8kvyw==",
|
||||
"workspaces": [
|
||||
"example",
|
||||
"component-generator",
|
||||
"www",
|
||||
"icons",
|
||||
"dependent-usage-analyzer"
|
||||
],
|
||||
"version": "22.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@openedx/paragon/-/paragon-22.3.0.tgz",
|
||||
"integrity": "sha512-tyPD14nNHfNPUzlbtspiBYFoGtrYa5+ANAVLA5ZXV1Oqunw4Etf8VMTj0DMII+BlZixBpc3gFuVHNbQBNd42Pw==",
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "^6.1.1",
|
||||
"@fortawesome/react-fontawesome": "^0.1.18",
|
||||
@@ -7064,6 +6878,21 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@testing-library/react-hooks/node_modules/react-error-boundary": {
|
||||
"version": "3.1.4",
|
||||
"resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.4.tgz",
|
||||
"integrity": "sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.12.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10",
|
||||
"npm": ">=6"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.13.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@testing-library/user-event": {
|
||||
"version": "13.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz",
|
||||
@@ -7362,6 +7191,29 @@
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
|
||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
|
||||
},
|
||||
"node_modules/@types/jsdom": {
|
||||
"version": "20.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-20.0.1.tgz",
|
||||
"integrity": "sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*",
|
||||
"@types/tough-cookie": "*",
|
||||
"parse5": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/jsdom/node_modules/parse5": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz",
|
||||
"integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"entities": "^4.4.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/inikulin/parse5?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/json-schema": {
|
||||
"version": "7.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz",
|
||||
@@ -7421,6 +7273,11 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
|
||||
"integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA=="
|
||||
},
|
||||
"node_modules/@types/picomatch": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/picomatch/-/picomatch-2.3.3.tgz",
|
||||
"integrity": "sha512-Yll76ZHikRFCyz/pffKGjrCwe/le2CDwOP5F210KQo27kpRE46U2rDnzikNlVn6/ezH3Mhn46bJMTfeVTtcYMg=="
|
||||
},
|
||||
"node_modules/@types/prettier": {
|
||||
"version": "2.7.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz",
|
||||
@@ -7488,6 +7345,11 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz",
|
||||
"integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ=="
|
||||
},
|
||||
"node_modules/@types/semver": {
|
||||
"version": "7.5.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz",
|
||||
"integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ=="
|
||||
},
|
||||
"node_modules/@types/send": {
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz",
|
||||
@@ -7551,6 +7413,12 @@
|
||||
"@types/jest": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/tough-cookie": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz",
|
||||
"integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@types/triple-beam": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.2.tgz",
|
||||
@@ -7594,6 +7462,229 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz",
|
||||
"integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA=="
|
||||
},
|
||||
"node_modules/@typescript-eslint/scope-manager": {
|
||||
"version": "6.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz",
|
||||
"integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "6.21.0",
|
||||
"@typescript-eslint/visitor-keys": "6.21.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^16.0.0 || >=18.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/types": {
|
||||
"version": "6.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz",
|
||||
"integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==",
|
||||
"engines": {
|
||||
"node": "^16.0.0 || >=18.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree": {
|
||||
"version": "6.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz",
|
||||
"integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "6.21.0",
|
||||
"@typescript-eslint/visitor-keys": "6.21.0",
|
||||
"debug": "^4.3.4",
|
||||
"globby": "^11.1.0",
|
||||
"is-glob": "^4.0.3",
|
||||
"minimatch": "9.0.3",
|
||||
"semver": "^7.5.4",
|
||||
"ts-api-utils": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^16.0.0 || >=18.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"typescript": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/array-union": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
|
||||
"integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/globby": {
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
|
||||
"integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
|
||||
"dependencies": {
|
||||
"array-union": "^2.1.0",
|
||||
"dir-glob": "^3.0.1",
|
||||
"fast-glob": "^3.2.9",
|
||||
"ignore": "^5.2.0",
|
||||
"merge2": "^1.4.1",
|
||||
"slash": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/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==",
|
||||
"dependencies": {
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
|
||||
"version": "9.0.3",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
|
||||
"integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/semver": {
|
||||
"version": "7.6.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
|
||||
"integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
|
||||
"dependencies": {
|
||||
"lru-cache": "^6.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/slash": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
|
||||
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
},
|
||||
"node_modules/@typescript-eslint/utils": {
|
||||
"version": "6.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz",
|
||||
"integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==",
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.4.0",
|
||||
"@types/json-schema": "^7.0.12",
|
||||
"@types/semver": "^7.5.0",
|
||||
"@typescript-eslint/scope-manager": "6.21.0",
|
||||
"@typescript-eslint/types": "6.21.0",
|
||||
"@typescript-eslint/typescript-estree": "6.21.0",
|
||||
"semver": "^7.5.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^16.0.0 || >=18.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^7.0.0 || ^8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/utils/node_modules/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==",
|
||||
"dependencies": {
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/utils/node_modules/semver": {
|
||||
"version": "7.6.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
|
||||
"integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
|
||||
"dependencies": {
|
||||
"lru-cache": "^6.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/utils/node_modules/yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
},
|
||||
"node_modules/@typescript-eslint/visitor-keys": {
|
||||
"version": "6.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz",
|
||||
"integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "6.21.0",
|
||||
"eslint-visitor-keys": "^3.4.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^16.0.0 || >=18.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": {
|
||||
"version": "3.4.3",
|
||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
|
||||
"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@webassemblyjs/ast": {
|
||||
"version": "1.11.6",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz",
|
||||
@@ -7776,6 +7867,12 @@
|
||||
"resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
|
||||
"integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ=="
|
||||
},
|
||||
"node_modules/@yarnpkg/lockfile": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz",
|
||||
"integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/abab": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
|
||||
@@ -8285,9 +8382,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/autoprefixer": {
|
||||
"version": "10.4.16",
|
||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz",
|
||||
"integrity": "sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==",
|
||||
"version": "10.4.19",
|
||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz",
|
||||
"integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@@ -8303,9 +8400,9 @@
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"browserslist": "^4.21.10",
|
||||
"caniuse-lite": "^1.0.30001538",
|
||||
"fraction.js": "^4.3.6",
|
||||
"browserslist": "^4.23.0",
|
||||
"caniuse-lite": "^1.0.30001599",
|
||||
"fraction.js": "^4.3.7",
|
||||
"normalize-range": "^0.1.2",
|
||||
"picocolors": "^1.0.0",
|
||||
"postcss-value-parser": "^4.2.0"
|
||||
@@ -8565,18 +8662,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz",
|
||||
"integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw=="
|
||||
},
|
||||
"node_modules/babel-plugin-formatjs/node_modules/typescript": {
|
||||
"version": "5.4.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz",
|
||||
"integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-istanbul": {
|
||||
"version": "6.1.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz",
|
||||
@@ -9003,6 +9088,18 @@
|
||||
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
|
||||
}
|
||||
},
|
||||
"node_modules/bs-logger": {
|
||||
"version": "0.2.6",
|
||||
"resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz",
|
||||
"integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"fast-json-stable-stringify": "2.x"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/bser": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
|
||||
@@ -9125,9 +9222,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001591",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001591.tgz",
|
||||
"integrity": "sha512-PCzRMei/vXjJyL5mJtzNiUCKP59dm8Apqc3PH8gJkMnMXZGox93RbE76jHsmLwmIo6/3nsYIpJtx0O7u5PqFuQ==",
|
||||
"version": "1.0.30001610",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001610.tgz",
|
||||
"integrity": "sha512-QFutAY4NgaelojVMjY63o6XlZyORPaLfyMnsl3HgnWdJUcX6K0oaJymHjH8PT5Gk7sTm8rvC/c5COUQKXqmOMA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@@ -9569,7 +9666,6 @@
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
|
||||
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.1",
|
||||
@@ -9582,14 +9678,12 @@
|
||||
"node_modules/cliui/node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||
"dev": true
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
},
|
||||
"node_modules/cliui/node_modules/is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -9598,7 +9692,6 @@
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
@@ -9612,7 +9705,6 @@
|
||||
"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,
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
@@ -10082,6 +10174,638 @@
|
||||
"js-yaml": "bin/js-yaml.js"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz",
|
||||
"integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/types": "^29.6.3",
|
||||
"chalk": "^4.0.0",
|
||||
"exit": "^0.1.2",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"jest-config": "^29.7.0",
|
||||
"jest-util": "^29.7.0",
|
||||
"prompts": "^2.0.1"
|
||||
},
|
||||
"bin": {
|
||||
"create-jest": "bin/create-jest.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/@jest/environment": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz",
|
||||
"integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/fake-timers": "^29.7.0",
|
||||
"@jest/types": "^29.6.3",
|
||||
"@types/node": "*",
|
||||
"jest-mock": "^29.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/@jest/fake-timers": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz",
|
||||
"integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/types": "^29.6.3",
|
||||
"@sinonjs/fake-timers": "^10.0.2",
|
||||
"@types/node": "*",
|
||||
"jest-message-util": "^29.7.0",
|
||||
"jest-mock": "^29.7.0",
|
||||
"jest-util": "^29.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/@jest/globals": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz",
|
||||
"integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/environment": "^29.7.0",
|
||||
"@jest/expect": "^29.7.0",
|
||||
"@jest/types": "^29.6.3",
|
||||
"jest-mock": "^29.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/@jest/source-map": {
|
||||
"version": "29.6.3",
|
||||
"resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz",
|
||||
"integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/trace-mapping": "^0.3.18",
|
||||
"callsites": "^3.0.0",
|
||||
"graceful-fs": "^4.2.9"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/@jest/test-sequencer": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz",
|
||||
"integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/test-result": "^29.7.0",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"jest-haste-map": "^29.7.0",
|
||||
"slash": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/@jest/transform": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz",
|
||||
"integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.11.6",
|
||||
"@jest/types": "^29.6.3",
|
||||
"@jridgewell/trace-mapping": "^0.3.18",
|
||||
"babel-plugin-istanbul": "^6.1.1",
|
||||
"chalk": "^4.0.0",
|
||||
"convert-source-map": "^2.0.0",
|
||||
"fast-json-stable-stringify": "^2.1.0",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"jest-haste-map": "^29.7.0",
|
||||
"jest-regex-util": "^29.6.3",
|
||||
"jest-util": "^29.7.0",
|
||||
"micromatch": "^4.0.4",
|
||||
"pirates": "^4.0.4",
|
||||
"slash": "^3.0.0",
|
||||
"write-file-atomic": "^4.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/@jest/types": {
|
||||
"version": "29.6.3",
|
||||
"resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
|
||||
"integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/schemas": "^29.6.3",
|
||||
"@types/istanbul-lib-coverage": "^2.0.0",
|
||||
"@types/istanbul-reports": "^3.0.0",
|
||||
"@types/node": "*",
|
||||
"@types/yargs": "^17.0.8",
|
||||
"chalk": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/@sinonjs/commons": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz",
|
||||
"integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"type-detect": "4.0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/@sinonjs/fake-timers": {
|
||||
"version": "10.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz",
|
||||
"integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@sinonjs/commons": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/@types/yargs": {
|
||||
"version": "17.0.32",
|
||||
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz",
|
||||
"integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/yargs-parser": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/ansi-styles": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
|
||||
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/babel-jest": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz",
|
||||
"integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/transform": "^29.7.0",
|
||||
"@types/babel__core": "^7.1.14",
|
||||
"babel-plugin-istanbul": "^6.1.1",
|
||||
"babel-preset-jest": "^29.6.3",
|
||||
"chalk": "^4.0.0",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"slash": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/babel-plugin-jest-hoist": {
|
||||
"version": "29.6.3",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz",
|
||||
"integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/template": "^7.3.3",
|
||||
"@babel/types": "^7.3.3",
|
||||
"@types/babel__core": "^7.1.14",
|
||||
"@types/babel__traverse": "^7.0.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/babel-preset-jest": {
|
||||
"version": "29.6.3",
|
||||
"resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz",
|
||||
"integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"babel-plugin-jest-hoist": "^29.6.3",
|
||||
"babel-preset-current-node-syntax": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/cjs-module-lexer": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz",
|
||||
"integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/create-jest/node_modules/convert-source-map": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
|
||||
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/create-jest/node_modules/emittery": {
|
||||
"version": "0.13.1",
|
||||
"resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz",
|
||||
"integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sindresorhus/emittery?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/jest-config": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz",
|
||||
"integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.11.6",
|
||||
"@jest/test-sequencer": "^29.7.0",
|
||||
"@jest/types": "^29.6.3",
|
||||
"babel-jest": "^29.7.0",
|
||||
"chalk": "^4.0.0",
|
||||
"ci-info": "^3.2.0",
|
||||
"deepmerge": "^4.2.2",
|
||||
"glob": "^7.1.3",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"jest-circus": "^29.7.0",
|
||||
"jest-environment-node": "^29.7.0",
|
||||
"jest-get-type": "^29.6.3",
|
||||
"jest-regex-util": "^29.6.3",
|
||||
"jest-resolve": "^29.7.0",
|
||||
"jest-runner": "^29.7.0",
|
||||
"jest-util": "^29.7.0",
|
||||
"jest-validate": "^29.7.0",
|
||||
"micromatch": "^4.0.4",
|
||||
"parse-json": "^5.2.0",
|
||||
"pretty-format": "^29.7.0",
|
||||
"slash": "^3.0.0",
|
||||
"strip-json-comments": "^3.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/node": "*",
|
||||
"ts-node": ">=9.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/node": {
|
||||
"optional": true
|
||||
},
|
||||
"ts-node": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/jest-docblock": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz",
|
||||
"integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"detect-newline": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/jest-environment-node": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz",
|
||||
"integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/environment": "^29.7.0",
|
||||
"@jest/fake-timers": "^29.7.0",
|
||||
"@jest/types": "^29.6.3",
|
||||
"@types/node": "*",
|
||||
"jest-mock": "^29.7.0",
|
||||
"jest-util": "^29.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/jest-haste-map": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz",
|
||||
"integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/types": "^29.6.3",
|
||||
"@types/graceful-fs": "^4.1.3",
|
||||
"@types/node": "*",
|
||||
"anymatch": "^3.0.3",
|
||||
"fb-watchman": "^2.0.0",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"jest-regex-util": "^29.6.3",
|
||||
"jest-util": "^29.7.0",
|
||||
"jest-worker": "^29.7.0",
|
||||
"micromatch": "^4.0.4",
|
||||
"walker": "^1.0.8"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "^2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/jest-leak-detector": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz",
|
||||
"integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"jest-get-type": "^29.6.3",
|
||||
"pretty-format": "^29.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/jest-mock": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz",
|
||||
"integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/types": "^29.6.3",
|
||||
"@types/node": "*",
|
||||
"jest-util": "^29.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/jest-regex-util": {
|
||||
"version": "29.6.3",
|
||||
"resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz",
|
||||
"integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/jest-resolve": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz",
|
||||
"integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"chalk": "^4.0.0",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"jest-haste-map": "^29.7.0",
|
||||
"jest-pnp-resolver": "^1.2.2",
|
||||
"jest-util": "^29.7.0",
|
||||
"jest-validate": "^29.7.0",
|
||||
"resolve": "^1.20.0",
|
||||
"resolve.exports": "^2.0.0",
|
||||
"slash": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/jest-runner": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz",
|
||||
"integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/console": "^29.7.0",
|
||||
"@jest/environment": "^29.7.0",
|
||||
"@jest/test-result": "^29.7.0",
|
||||
"@jest/transform": "^29.7.0",
|
||||
"@jest/types": "^29.6.3",
|
||||
"@types/node": "*",
|
||||
"chalk": "^4.0.0",
|
||||
"emittery": "^0.13.1",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"jest-docblock": "^29.7.0",
|
||||
"jest-environment-node": "^29.7.0",
|
||||
"jest-haste-map": "^29.7.0",
|
||||
"jest-leak-detector": "^29.7.0",
|
||||
"jest-message-util": "^29.7.0",
|
||||
"jest-resolve": "^29.7.0",
|
||||
"jest-runtime": "^29.7.0",
|
||||
"jest-util": "^29.7.0",
|
||||
"jest-watcher": "^29.7.0",
|
||||
"jest-worker": "^29.7.0",
|
||||
"p-limit": "^3.1.0",
|
||||
"source-map-support": "0.5.13"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/jest-runtime": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz",
|
||||
"integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/environment": "^29.7.0",
|
||||
"@jest/fake-timers": "^29.7.0",
|
||||
"@jest/globals": "^29.7.0",
|
||||
"@jest/source-map": "^29.6.3",
|
||||
"@jest/test-result": "^29.7.0",
|
||||
"@jest/transform": "^29.7.0",
|
||||
"@jest/types": "^29.6.3",
|
||||
"@types/node": "*",
|
||||
"chalk": "^4.0.0",
|
||||
"cjs-module-lexer": "^1.0.0",
|
||||
"collect-v8-coverage": "^1.0.0",
|
||||
"glob": "^7.1.3",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"jest-haste-map": "^29.7.0",
|
||||
"jest-message-util": "^29.7.0",
|
||||
"jest-mock": "^29.7.0",
|
||||
"jest-regex-util": "^29.6.3",
|
||||
"jest-resolve": "^29.7.0",
|
||||
"jest-snapshot": "^29.7.0",
|
||||
"jest-util": "^29.7.0",
|
||||
"slash": "^3.0.0",
|
||||
"strip-bom": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/jest-snapshot": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz",
|
||||
"integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.11.6",
|
||||
"@babel/generator": "^7.7.2",
|
||||
"@babel/plugin-syntax-jsx": "^7.7.2",
|
||||
"@babel/plugin-syntax-typescript": "^7.7.2",
|
||||
"@babel/types": "^7.3.3",
|
||||
"@jest/expect-utils": "^29.7.0",
|
||||
"@jest/transform": "^29.7.0",
|
||||
"@jest/types": "^29.6.3",
|
||||
"babel-preset-current-node-syntax": "^1.0.0",
|
||||
"chalk": "^4.0.0",
|
||||
"expect": "^29.7.0",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"jest-diff": "^29.7.0",
|
||||
"jest-get-type": "^29.6.3",
|
||||
"jest-matcher-utils": "^29.7.0",
|
||||
"jest-message-util": "^29.7.0",
|
||||
"jest-util": "^29.7.0",
|
||||
"natural-compare": "^1.4.0",
|
||||
"pretty-format": "^29.7.0",
|
||||
"semver": "^7.5.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/jest-util": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz",
|
||||
"integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/types": "^29.6.3",
|
||||
"@types/node": "*",
|
||||
"chalk": "^4.0.0",
|
||||
"ci-info": "^3.2.0",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"picomatch": "^2.2.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/jest-validate": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz",
|
||||
"integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/types": "^29.6.3",
|
||||
"camelcase": "^6.2.0",
|
||||
"chalk": "^4.0.0",
|
||||
"jest-get-type": "^29.6.3",
|
||||
"leven": "^3.1.0",
|
||||
"pretty-format": "^29.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/jest-watcher": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz",
|
||||
"integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/test-result": "^29.7.0",
|
||||
"@jest/types": "^29.6.3",
|
||||
"@types/node": "*",
|
||||
"ansi-escapes": "^4.2.1",
|
||||
"chalk": "^4.0.0",
|
||||
"emittery": "^0.13.1",
|
||||
"jest-util": "^29.7.0",
|
||||
"string-length": "^4.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/pretty-format": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
|
||||
"integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/schemas": "^29.6.3",
|
||||
"ansi-styles": "^5.0.0",
|
||||
"react-is": "^18.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/react-is": {
|
||||
"version": "18.3.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
|
||||
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/create-jest/node_modules/semver": {
|
||||
"version": "7.6.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
|
||||
"integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/slash": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
|
||||
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/source-map-support": {
|
||||
"version": "0.5.13",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz",
|
||||
"integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"source-map": "^0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/create-jest/node_modules/write-file-atomic": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz",
|
||||
"integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"imurmurhash": "^0.1.4",
|
||||
"signal-exit": "^3.0.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||
@@ -10222,6 +10946,25 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/cssnano": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.0.3.tgz",
|
||||
"integrity": "sha512-MRq4CIj8pnyZpcI2qs6wswoYoDD1t0aL28n+41c1Ukcpm56m1h6mCexIHBGjfZfnTqtGSSCP4/fB1ovxgjBOiw==",
|
||||
"dependencies": {
|
||||
"cssnano-preset-default": "^6.0.3",
|
||||
"lilconfig": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14 || ^16 || >=18.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/cssnano"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.31"
|
||||
}
|
||||
},
|
||||
"node_modules/cssnano-preset-default": {
|
||||
"version": "6.0.5",
|
||||
"resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.0.5.tgz",
|
||||
@@ -10436,6 +11179,20 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/dedent": {
|
||||
"version": "1.5.3",
|
||||
"resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz",
|
||||
"integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==",
|
||||
"peer": true,
|
||||
"peerDependencies": {
|
||||
"babel-plugin-macros": "^3.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"babel-plugin-macros": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/deep-equal": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.1.tgz",
|
||||
@@ -11503,6 +12260,59 @@
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-formatjs": {
|
||||
"version": "4.13.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-formatjs/-/eslint-plugin-formatjs-4.13.0.tgz",
|
||||
"integrity": "sha512-sxgHQNyVclNRO7aydGwxohwxYR03/oRDW0uUXFWayNMPTlnb9sET3LCovBjvQF7qAHDGFDcLwg4ECSyui4nG8A==",
|
||||
"dependencies": {
|
||||
"@formatjs/icu-messageformat-parser": "2.7.6",
|
||||
"@formatjs/ts-transformer": "3.13.12",
|
||||
"@types/eslint": "7 || 8",
|
||||
"@types/picomatch": "^2.3.0",
|
||||
"@typescript-eslint/utils": "^6.18.1",
|
||||
"emoji-regex": "^10.2.1",
|
||||
"magic-string": "^0.30.0",
|
||||
"picomatch": "^2.3.1",
|
||||
"tslib": "2.6.2",
|
||||
"typescript": "5",
|
||||
"unicode-emoji-utils": "^1.2.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "7 || 8"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-formatjs/node_modules/@formatjs/ts-transformer": {
|
||||
"version": "3.13.12",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/ts-transformer/-/ts-transformer-3.13.12.tgz",
|
||||
"integrity": "sha512-uf1+DgbsCrzHAg7uIf0QlzpIkHYxRSRig5iJa9FaoUNIDZzNEE2oW/uLLLq7I9Z2FLIPhbmgq8hbW40FoQv+Fg==",
|
||||
"dependencies": {
|
||||
"@formatjs/icu-messageformat-parser": "2.7.6",
|
||||
"@types/json-stable-stringify": "^1.0.32",
|
||||
"@types/node": "14 || 16 || 17",
|
||||
"chalk": "^4.0.0",
|
||||
"json-stable-stringify": "^1.0.1",
|
||||
"tslib": "^2.4.0",
|
||||
"typescript": "5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"ts-jest": ">=27"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"ts-jest": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-formatjs/node_modules/@types/node": {
|
||||
"version": "17.0.45",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz",
|
||||
"integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw=="
|
||||
},
|
||||
"node_modules/eslint-plugin-formatjs/node_modules/emoji-regex": {
|
||||
"version": "10.3.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz",
|
||||
"integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw=="
|
||||
},
|
||||
"node_modules/eslint-plugin-import": {
|
||||
"version": "2.27.5",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz",
|
||||
@@ -12042,15 +12852,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/expect": {
|
||||
"version": "29.6.4",
|
||||
"resolved": "https://registry.npmjs.org/expect/-/expect-29.6.4.tgz",
|
||||
"integrity": "sha512-F2W2UyQ8XYyftHT57dtfg8Ue3X5qLgm2sSug0ivvLRH/VKNRL/pDxg/TH7zVzbQB0tu80clNFy6LU7OS/VSEKA==",
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz",
|
||||
"integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==",
|
||||
"dependencies": {
|
||||
"@jest/expect-utils": "^29.6.4",
|
||||
"@jest/expect-utils": "^29.7.0",
|
||||
"jest-get-type": "^29.6.3",
|
||||
"jest-matcher-utils": "^29.6.4",
|
||||
"jest-message-util": "^29.6.3",
|
||||
"jest-util": "^29.6.3"
|
||||
"jest-matcher-utils": "^29.7.0",
|
||||
"jest-message-util": "^29.7.0",
|
||||
"jest-util": "^29.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
@@ -12073,17 +12883,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/expect/node_modules/@types/yargs": {
|
||||
"version": "17.0.24",
|
||||
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz",
|
||||
"integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==",
|
||||
"version": "17.0.32",
|
||||
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz",
|
||||
"integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==",
|
||||
"dependencies": {
|
||||
"@types/yargs-parser": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/expect/node_modules/jest-util": {
|
||||
"version": "29.6.3",
|
||||
"resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.6.3.tgz",
|
||||
"integrity": "sha512-QUjna/xSy4B32fzcKTSz1w7YYzgiHrjjJjevdRf61HYk998R5vVMMNmrHESYZVDS5DSWs+1srPLPKxXPkeSDOA==",
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz",
|
||||
"integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==",
|
||||
"dependencies": {
|
||||
"@jest/types": "^29.6.3",
|
||||
"@types/node": "*",
|
||||
@@ -12543,6 +13353,15 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/find-yarn-workspace-root": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz",
|
||||
"integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"micromatch": "^4.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/flat": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
|
||||
@@ -12787,9 +13606,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/fraction.js": {
|
||||
"version": "4.3.6",
|
||||
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.6.tgz",
|
||||
"integrity": "sha512-n2aZ9tNfYDwaHhvFTkhFErqOMIb8uyzSQ+vGJBjZyanAKZVbGUQ1sngfk9FdkBw7G26O7AgNjLcecLffD1c7eg==",
|
||||
"version": "4.3.7",
|
||||
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
|
||||
"integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
@@ -13529,6 +14348,37 @@
|
||||
"node": ">= 12"
|
||||
}
|
||||
},
|
||||
"node_modules/html-webpack-plugin": {
|
||||
"version": "5.6.0",
|
||||
"resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz",
|
||||
"integrity": "sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==",
|
||||
"dependencies": {
|
||||
"@types/html-minifier-terser": "^6.0.0",
|
||||
"html-minifier-terser": "^6.0.2",
|
||||
"lodash": "^4.17.21",
|
||||
"pretty-error": "^4.0.0",
|
||||
"tapable": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/html-webpack-plugin"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@rspack/core": "0.x || 1.x",
|
||||
"webpack": "^5.20.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@rspack/core": {
|
||||
"optional": true
|
||||
},
|
||||
"webpack": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/htmlparser2": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz",
|
||||
@@ -14956,7 +15806,6 @@
|
||||
"version": "26.6.3",
|
||||
"resolved": "https://registry.npmjs.org/jest/-/jest-26.6.3.tgz",
|
||||
"integrity": "sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jest/core": "^26.6.3",
|
||||
"import-local": "^3.0.2",
|
||||
@@ -14973,7 +15822,6 @@
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.6.2.tgz",
|
||||
"integrity": "sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jest/types": "^26.6.2",
|
||||
"execa": "^4.0.0",
|
||||
@@ -14987,7 +15835,6 @@
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz",
|
||||
"integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"cross-spawn": "^7.0.0",
|
||||
"get-stream": "^5.0.0",
|
||||
@@ -15010,7 +15857,6 @@
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
|
||||
"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"pump": "^3.0.0"
|
||||
},
|
||||
@@ -15025,16 +15871,436 @@
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
|
||||
"integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-circus": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz",
|
||||
"integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/environment": "^29.7.0",
|
||||
"@jest/expect": "^29.7.0",
|
||||
"@jest/test-result": "^29.7.0",
|
||||
"@jest/types": "^29.6.3",
|
||||
"@types/node": "*",
|
||||
"chalk": "^4.0.0",
|
||||
"co": "^4.6.0",
|
||||
"dedent": "^1.0.0",
|
||||
"is-generator-fn": "^2.0.0",
|
||||
"jest-each": "^29.7.0",
|
||||
"jest-matcher-utils": "^29.7.0",
|
||||
"jest-message-util": "^29.7.0",
|
||||
"jest-runtime": "^29.7.0",
|
||||
"jest-snapshot": "^29.7.0",
|
||||
"jest-util": "^29.7.0",
|
||||
"p-limit": "^3.1.0",
|
||||
"pretty-format": "^29.7.0",
|
||||
"pure-rand": "^6.0.0",
|
||||
"slash": "^3.0.0",
|
||||
"stack-utils": "^2.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-circus/node_modules/@jest/environment": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz",
|
||||
"integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/fake-timers": "^29.7.0",
|
||||
"@jest/types": "^29.6.3",
|
||||
"@types/node": "*",
|
||||
"jest-mock": "^29.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-circus/node_modules/@jest/fake-timers": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz",
|
||||
"integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/types": "^29.6.3",
|
||||
"@sinonjs/fake-timers": "^10.0.2",
|
||||
"@types/node": "*",
|
||||
"jest-message-util": "^29.7.0",
|
||||
"jest-mock": "^29.7.0",
|
||||
"jest-util": "^29.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-circus/node_modules/@jest/globals": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz",
|
||||
"integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/environment": "^29.7.0",
|
||||
"@jest/expect": "^29.7.0",
|
||||
"@jest/types": "^29.6.3",
|
||||
"jest-mock": "^29.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-circus/node_modules/@jest/source-map": {
|
||||
"version": "29.6.3",
|
||||
"resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz",
|
||||
"integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/trace-mapping": "^0.3.18",
|
||||
"callsites": "^3.0.0",
|
||||
"graceful-fs": "^4.2.9"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-circus/node_modules/@jest/transform": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz",
|
||||
"integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.11.6",
|
||||
"@jest/types": "^29.6.3",
|
||||
"@jridgewell/trace-mapping": "^0.3.18",
|
||||
"babel-plugin-istanbul": "^6.1.1",
|
||||
"chalk": "^4.0.0",
|
||||
"convert-source-map": "^2.0.0",
|
||||
"fast-json-stable-stringify": "^2.1.0",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"jest-haste-map": "^29.7.0",
|
||||
"jest-regex-util": "^29.6.3",
|
||||
"jest-util": "^29.7.0",
|
||||
"micromatch": "^4.0.4",
|
||||
"pirates": "^4.0.4",
|
||||
"slash": "^3.0.0",
|
||||
"write-file-atomic": "^4.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-circus/node_modules/@jest/types": {
|
||||
"version": "29.6.3",
|
||||
"resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
|
||||
"integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/schemas": "^29.6.3",
|
||||
"@types/istanbul-lib-coverage": "^2.0.0",
|
||||
"@types/istanbul-reports": "^3.0.0",
|
||||
"@types/node": "*",
|
||||
"@types/yargs": "^17.0.8",
|
||||
"chalk": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-circus/node_modules/@sinonjs/commons": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz",
|
||||
"integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"type-detect": "4.0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-circus/node_modules/@sinonjs/fake-timers": {
|
||||
"version": "10.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz",
|
||||
"integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@sinonjs/commons": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-circus/node_modules/@types/yargs": {
|
||||
"version": "17.0.32",
|
||||
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz",
|
||||
"integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/yargs-parser": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-circus/node_modules/ansi-styles": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
|
||||
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-circus/node_modules/cjs-module-lexer": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz",
|
||||
"integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/jest-circus/node_modules/convert-source-map": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
|
||||
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/jest-circus/node_modules/jest-each": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz",
|
||||
"integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/types": "^29.6.3",
|
||||
"chalk": "^4.0.0",
|
||||
"jest-get-type": "^29.6.3",
|
||||
"jest-util": "^29.7.0",
|
||||
"pretty-format": "^29.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-circus/node_modules/jest-haste-map": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz",
|
||||
"integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/types": "^29.6.3",
|
||||
"@types/graceful-fs": "^4.1.3",
|
||||
"@types/node": "*",
|
||||
"anymatch": "^3.0.3",
|
||||
"fb-watchman": "^2.0.0",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"jest-regex-util": "^29.6.3",
|
||||
"jest-util": "^29.7.0",
|
||||
"jest-worker": "^29.7.0",
|
||||
"micromatch": "^4.0.4",
|
||||
"walker": "^1.0.8"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "^2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-circus/node_modules/jest-mock": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz",
|
||||
"integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/types": "^29.6.3",
|
||||
"@types/node": "*",
|
||||
"jest-util": "^29.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-circus/node_modules/jest-regex-util": {
|
||||
"version": "29.6.3",
|
||||
"resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz",
|
||||
"integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-circus/node_modules/jest-resolve": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz",
|
||||
"integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"chalk": "^4.0.0",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"jest-haste-map": "^29.7.0",
|
||||
"jest-pnp-resolver": "^1.2.2",
|
||||
"jest-util": "^29.7.0",
|
||||
"jest-validate": "^29.7.0",
|
||||
"resolve": "^1.20.0",
|
||||
"resolve.exports": "^2.0.0",
|
||||
"slash": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-circus/node_modules/jest-runtime": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz",
|
||||
"integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/environment": "^29.7.0",
|
||||
"@jest/fake-timers": "^29.7.0",
|
||||
"@jest/globals": "^29.7.0",
|
||||
"@jest/source-map": "^29.6.3",
|
||||
"@jest/test-result": "^29.7.0",
|
||||
"@jest/transform": "^29.7.0",
|
||||
"@jest/types": "^29.6.3",
|
||||
"@types/node": "*",
|
||||
"chalk": "^4.0.0",
|
||||
"cjs-module-lexer": "^1.0.0",
|
||||
"collect-v8-coverage": "^1.0.0",
|
||||
"glob": "^7.1.3",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"jest-haste-map": "^29.7.0",
|
||||
"jest-message-util": "^29.7.0",
|
||||
"jest-mock": "^29.7.0",
|
||||
"jest-regex-util": "^29.6.3",
|
||||
"jest-resolve": "^29.7.0",
|
||||
"jest-snapshot": "^29.7.0",
|
||||
"jest-util": "^29.7.0",
|
||||
"slash": "^3.0.0",
|
||||
"strip-bom": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-circus/node_modules/jest-snapshot": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz",
|
||||
"integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.11.6",
|
||||
"@babel/generator": "^7.7.2",
|
||||
"@babel/plugin-syntax-jsx": "^7.7.2",
|
||||
"@babel/plugin-syntax-typescript": "^7.7.2",
|
||||
"@babel/types": "^7.3.3",
|
||||
"@jest/expect-utils": "^29.7.0",
|
||||
"@jest/transform": "^29.7.0",
|
||||
"@jest/types": "^29.6.3",
|
||||
"babel-preset-current-node-syntax": "^1.0.0",
|
||||
"chalk": "^4.0.0",
|
||||
"expect": "^29.7.0",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"jest-diff": "^29.7.0",
|
||||
"jest-get-type": "^29.6.3",
|
||||
"jest-matcher-utils": "^29.7.0",
|
||||
"jest-message-util": "^29.7.0",
|
||||
"jest-util": "^29.7.0",
|
||||
"natural-compare": "^1.4.0",
|
||||
"pretty-format": "^29.7.0",
|
||||
"semver": "^7.5.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-circus/node_modules/jest-util": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz",
|
||||
"integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/types": "^29.6.3",
|
||||
"@types/node": "*",
|
||||
"chalk": "^4.0.0",
|
||||
"ci-info": "^3.2.0",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"picomatch": "^2.2.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-circus/node_modules/jest-validate": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz",
|
||||
"integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/types": "^29.6.3",
|
||||
"camelcase": "^6.2.0",
|
||||
"chalk": "^4.0.0",
|
||||
"jest-get-type": "^29.6.3",
|
||||
"leven": "^3.1.0",
|
||||
"pretty-format": "^29.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-circus/node_modules/pretty-format": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
|
||||
"integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/schemas": "^29.6.3",
|
||||
"ansi-styles": "^5.0.0",
|
||||
"react-is": "^18.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-circus/node_modules/react-is": {
|
||||
"version": "18.3.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
|
||||
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/jest-circus/node_modules/semver": {
|
||||
"version": "7.6.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
|
||||
"integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-circus/node_modules/slash": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
|
||||
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-circus/node_modules/write-file-atomic": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz",
|
||||
"integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"imurmurhash": "^0.1.4",
|
||||
"signal-exit": "^3.0.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-cli": {
|
||||
"version": "26.6.3",
|
||||
"resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz",
|
||||
"integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jest/core": "^26.6.3",
|
||||
"@jest/test-result": "^26.6.2",
|
||||
@@ -15061,7 +16327,6 @@
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz",
|
||||
"integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jest/types": "^26.6.2",
|
||||
"@types/node": "*",
|
||||
@@ -15078,7 +16343,6 @@
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz",
|
||||
"integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jest/console": "^26.6.2",
|
||||
"@jest/types": "^26.6.2",
|
||||
@@ -15093,7 +16357,6 @@
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
|
||||
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
@@ -15102,7 +16365,6 @@
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
|
||||
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
@@ -15112,14 +16374,12 @@
|
||||
"node_modules/jest-cli/node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||
"dev": true
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
},
|
||||
"node_modules/jest-cli/node_modules/find-up": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
|
||||
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"locate-path": "^5.0.0",
|
||||
"path-exists": "^4.0.0"
|
||||
@@ -15132,7 +16392,6 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -15141,7 +16400,6 @@
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz",
|
||||
"integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.0.0",
|
||||
"@jest/types": "^26.6.2",
|
||||
@@ -15161,7 +16419,6 @@
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
|
||||
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"p-locate": "^4.1.0"
|
||||
},
|
||||
@@ -15173,7 +16430,6 @@
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
|
||||
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"p-try": "^2.0.0"
|
||||
},
|
||||
@@ -15188,7 +16444,6 @@
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
|
||||
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"p-limit": "^2.2.0"
|
||||
},
|
||||
@@ -15200,7 +16455,6 @@
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz",
|
||||
"integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jest/types": "^26.6.2",
|
||||
"ansi-regex": "^5.0.0",
|
||||
@@ -15215,7 +16469,6 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
|
||||
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -15224,7 +16477,6 @@
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
@@ -15237,14 +16489,12 @@
|
||||
"node_modules/jest-cli/node_modules/y18n": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
|
||||
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="
|
||||
},
|
||||
"node_modules/jest-cli/node_modules/yargs": {
|
||||
"version": "15.4.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
|
||||
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"cliui": "^6.0.0",
|
||||
"decamelize": "^1.2.0",
|
||||
@@ -15266,7 +16516,6 @@
|
||||
"version": "18.1.3",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
|
||||
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
@@ -15348,14 +16597,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/jest-diff": {
|
||||
"version": "29.6.4",
|
||||
"resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.6.4.tgz",
|
||||
"integrity": "sha512-9F48UxR9e4XOEZvoUXEHSWY4qC4zERJaOfrbBg9JpbJOO43R1vN76REt/aMGZoY6GD5g84nnJiBIVlscegefpw==",
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz",
|
||||
"integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==",
|
||||
"dependencies": {
|
||||
"chalk": "^4.0.0",
|
||||
"diff-sequences": "^29.6.3",
|
||||
"jest-get-type": "^29.6.3",
|
||||
"pretty-format": "^29.6.3"
|
||||
"pretty-format": "^29.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
@@ -15373,9 +16622,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/jest-diff/node_modules/pretty-format": {
|
||||
"version": "29.6.3",
|
||||
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.3.tgz",
|
||||
"integrity": "sha512-ZsBgjVhFAj5KeK+nHfF1305/By3lechHQSMWCTl8iHSbfOm2TN5nHEtFc/+W7fAyUeCs2n5iow72gld4gW0xDw==",
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
|
||||
"integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
|
||||
"dependencies": {
|
||||
"@jest/schemas": "^29.6.3",
|
||||
"ansi-styles": "^5.0.0",
|
||||
@@ -15386,9 +16635,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/jest-diff/node_modules/react-is": {
|
||||
"version": "18.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
|
||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
|
||||
"version": "18.3.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
|
||||
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="
|
||||
},
|
||||
"node_modules/jest-docblock": {
|
||||
"version": "26.0.0",
|
||||
@@ -15712,14 +16961,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/jest-matcher-utils": {
|
||||
"version": "29.6.4",
|
||||
"resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.6.4.tgz",
|
||||
"integrity": "sha512-KSzwyzGvK4HcfnserYqJHYi7sZVqdREJ9DMPAKVbS98JsIAvumihaNUbjrWw0St7p9IY7A9UskCW5MYlGmBQFQ==",
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz",
|
||||
"integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==",
|
||||
"dependencies": {
|
||||
"chalk": "^4.0.0",
|
||||
"jest-diff": "^29.6.4",
|
||||
"jest-diff": "^29.7.0",
|
||||
"jest-get-type": "^29.6.3",
|
||||
"pretty-format": "^29.6.3"
|
||||
"pretty-format": "^29.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
@@ -15737,9 +16986,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/jest-matcher-utils/node_modules/pretty-format": {
|
||||
"version": "29.6.3",
|
||||
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.3.tgz",
|
||||
"integrity": "sha512-ZsBgjVhFAj5KeK+nHfF1305/By3lechHQSMWCTl8iHSbfOm2TN5nHEtFc/+W7fAyUeCs2n5iow72gld4gW0xDw==",
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
|
||||
"integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
|
||||
"dependencies": {
|
||||
"@jest/schemas": "^29.6.3",
|
||||
"ansi-styles": "^5.0.0",
|
||||
@@ -15750,9 +16999,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/jest-matcher-utils/node_modules/react-is": {
|
||||
"version": "18.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
|
||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
|
||||
"version": "18.3.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
|
||||
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="
|
||||
},
|
||||
"node_modules/jest-message-util": {
|
||||
"version": "29.7.0",
|
||||
@@ -15892,7 +17141,6 @@
|
||||
"version": "26.6.3",
|
||||
"resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz",
|
||||
"integrity": "sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jest/types": "^26.6.2",
|
||||
"jest-regex-util": "^26.0.0",
|
||||
@@ -16492,7 +17740,6 @@
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz",
|
||||
"integrity": "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jest/test-result": "^26.6.2",
|
||||
"@jest/types": "^26.6.2",
|
||||
@@ -16510,7 +17757,6 @@
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz",
|
||||
"integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jest/types": "^26.6.2",
|
||||
"@types/node": "*",
|
||||
@@ -16527,7 +17773,6 @@
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz",
|
||||
"integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jest/console": "^26.6.2",
|
||||
"@jest/types": "^26.6.2",
|
||||
@@ -16542,7 +17787,6 @@
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz",
|
||||
"integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.0.0",
|
||||
"@jest/types": "^26.6.2",
|
||||
@@ -16562,7 +17806,6 @@
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz",
|
||||
"integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jest/types": "^26.6.2",
|
||||
"ansi-regex": "^5.0.0",
|
||||
@@ -16577,7 +17820,6 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
|
||||
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -16595,7 +17837,6 @@
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz",
|
||||
"integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*",
|
||||
@@ -16611,7 +17852,6 @@
|
||||
"version": "29.6.3",
|
||||
"resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
|
||||
"integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/schemas": "^29.6.3",
|
||||
@@ -16629,7 +17869,6 @@
|
||||
"version": "17.0.32",
|
||||
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz",
|
||||
"integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/yargs-parser": "*"
|
||||
@@ -16639,7 +17878,6 @@
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz",
|
||||
"integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/types": "^29.6.3",
|
||||
@@ -16657,7 +17895,6 @@
|
||||
"version": "8.1.1",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
|
||||
"integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"has-flag": "^4.0.0"
|
||||
@@ -16931,6 +18168,15 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/klaw-sync": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz",
|
||||
"integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.1.11"
|
||||
}
|
||||
},
|
||||
"node_modules/kleur": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
|
||||
@@ -16995,6 +18241,17 @@
|
||||
"immediate": "~3.0.5"
|
||||
}
|
||||
},
|
||||
"node_modules/lilconfig": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz",
|
||||
"integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antonk52"
|
||||
}
|
||||
},
|
||||
"node_modules/lines-and-columns": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
|
||||
@@ -17248,6 +18505,17 @@
|
||||
"lz-string": "bin/bin.js"
|
||||
}
|
||||
},
|
||||
"node_modules/magic-string": {
|
||||
"version": "0.30.9",
|
||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.9.tgz",
|
||||
"integrity": "sha512-S1+hd+dIrC8EZqKyT9DstTH/0Z+f76kmmvZnkfQVmOpDEF9iVgdYif3Q/pIWHmCoo59bQVGW0kVL3e2nl+9+Sw==",
|
||||
"dependencies": {
|
||||
"@jridgewell/sourcemap-codec": "^1.4.15"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/mailto-link": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mailto-link/-/mailto-link-2.0.0.tgz",
|
||||
@@ -17299,6 +18567,12 @@
|
||||
"semver": "bin/semver"
|
||||
}
|
||||
},
|
||||
"node_modules/make-error": {
|
||||
"version": "1.3.6",
|
||||
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
||||
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/makeerror": {
|
||||
"version": "1.0.12",
|
||||
"resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
|
||||
@@ -18910,6 +20184,109 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/patch-package": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/patch-package/-/patch-package-8.0.0.tgz",
|
||||
"integrity": "sha512-da8BVIhzjtgScwDJ2TtKsfT5JFWz1hYoBl9rUQ1f38MC2HwnEIkK8VN3dKMKcP7P7bvvgzNDbfNHtx3MsQb5vA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@yarnpkg/lockfile": "^1.1.0",
|
||||
"chalk": "^4.1.2",
|
||||
"ci-info": "^3.7.0",
|
||||
"cross-spawn": "^7.0.3",
|
||||
"find-yarn-workspace-root": "^2.0.0",
|
||||
"fs-extra": "^9.0.0",
|
||||
"json-stable-stringify": "^1.0.2",
|
||||
"klaw-sync": "^6.0.0",
|
||||
"minimist": "^1.2.6",
|
||||
"open": "^7.4.2",
|
||||
"rimraf": "^2.6.3",
|
||||
"semver": "^7.5.3",
|
||||
"slash": "^2.0.0",
|
||||
"tmp": "^0.0.33",
|
||||
"yaml": "^2.2.2"
|
||||
},
|
||||
"bin": {
|
||||
"patch-package": "index.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14",
|
||||
"npm": ">5"
|
||||
}
|
||||
},
|
||||
"node_modules/patch-package/node_modules/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,
|
||||
"dependencies": {
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/patch-package/node_modules/open": {
|
||||
"version": "7.4.2",
|
||||
"resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz",
|
||||
"integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-docker": "^2.0.0",
|
||||
"is-wsl": "^2.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/patch-package/node_modules/rimraf": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
|
||||
"integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"glob": "^7.1.3"
|
||||
},
|
||||
"bin": {
|
||||
"rimraf": "bin.js"
|
||||
}
|
||||
},
|
||||
"node_modules/patch-package/node_modules/semver": {
|
||||
"version": "7.6.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
|
||||
"integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"lru-cache": "^6.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/patch-package/node_modules/yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/patch-package/node_modules/yaml": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz",
|
||||
"integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"yaml": "bin.mjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/path-exists": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
||||
@@ -19257,9 +20634,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.4.32",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz",
|
||||
"integrity": "sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==",
|
||||
"version": "8.4.38",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
|
||||
"integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@@ -19277,7 +20654,7 @@
|
||||
"dependencies": {
|
||||
"nanoid": "^3.3.7",
|
||||
"picocolors": "^1.0.0",
|
||||
"source-map-js": "^1.0.2"
|
||||
"source-map-js": "^1.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || >=14"
|
||||
@@ -19331,9 +20708,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-custom-media": {
|
||||
"version": "10.0.2",
|
||||
"resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-10.0.2.tgz",
|
||||
"integrity": "sha512-zcEFNRmDm2fZvTPdI1pIW3W//UruMcLosmMiCdpQnrCsTRzWlKQPYMa1ud9auL0BmrryKK1+JjIGn19K0UjO/w==",
|
||||
"version": "10.0.4",
|
||||
"resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-10.0.4.tgz",
|
||||
"integrity": "sha512-Ubs7O3wj2prghaKRa68VHBvuy3KnTQ0zbGwqDYY1mntxJD0QL2AeiAy+AMfl3HBedTCVr2IcFNktwty9YpSskA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@@ -19345,10 +20722,10 @@
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"@csstools/cascade-layer-name-parser": "^1.0.5",
|
||||
"@csstools/css-parser-algorithms": "^2.3.2",
|
||||
"@csstools/css-tokenizer": "^2.2.1",
|
||||
"@csstools/media-query-list-parser": "^2.1.5"
|
||||
"@csstools/cascade-layer-name-parser": "^1.0.9",
|
||||
"@csstools/css-parser-algorithms": "^2.6.1",
|
||||
"@csstools/css-tokenizer": "^2.2.4",
|
||||
"@csstools/media-query-list-parser": "^2.1.9"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14 || ^16 || >=18"
|
||||
@@ -19824,6 +21201,20 @@
|
||||
"postcss": "^8.4.31"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-rtlcss": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-rtlcss/-/postcss-rtlcss-5.1.0.tgz",
|
||||
"integrity": "sha512-FjZ8HPwr6dWR1Jzzz+TZqkEhkfLiR7sKgsHTDqrYGd51KtZdaDpdJ5aqHmqWoXZsSyJgBIkwZPt5JoEPvkX3Nw==",
|
||||
"dependencies": {
|
||||
"rtlcss": "4.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.21"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-selector-parser": {
|
||||
"version": "6.0.15",
|
||||
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz",
|
||||
@@ -20098,6 +21489,22 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/pure-rand": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz",
|
||||
"integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/dubzzz"
|
||||
},
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/fast-check"
|
||||
}
|
||||
],
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/purgecss": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/purgecss/-/purgecss-5.0.0.tgz",
|
||||
@@ -20466,16 +21873,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-error-boundary": {
|
||||
"version": "3.1.4",
|
||||
"resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.4.tgz",
|
||||
"integrity": "sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==",
|
||||
"version": "4.0.13",
|
||||
"resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-4.0.13.tgz",
|
||||
"integrity": "sha512-b6PwbdSv8XeOSYvjt8LpgpKrZ0yGdtZokYwkwV2wlcZbxgopHX/hgPl5VgpnoVOWd868n1hktM8Qm4b+02MiLQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.12.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10",
|
||||
"npm": ">=6"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.13.1"
|
||||
}
|
||||
@@ -20570,7 +21974,6 @@
|
||||
"version": "6.6.3",
|
||||
"resolved": "https://registry.npmjs.org/react-intl/-/react-intl-6.6.3.tgz",
|
||||
"integrity": "sha512-vLKI0f+Q3pXD5szmCUPikTY7CJDPtxCBMG5YABQZ3IGEKzNB47zlvXyasUFfT25zpgQXeOfhRCdx4q6ubuR6bA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@formatjs/ecma402-abstract": "1.18.2",
|
||||
"@formatjs/icu-messageformat-parser": "2.7.6",
|
||||
@@ -20597,7 +22000,6 @@
|
||||
"version": "1.18.2",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.18.2.tgz",
|
||||
"integrity": "sha512-+QoPW4csYALsQIl8GbN14igZzDbuwzcpWrku9nyMXlaqAlwRBgl5V+p0vWMGFqHOw37czNXaP/lEk4wbLgcmtA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@formatjs/intl-localematcher": "0.5.4",
|
||||
"tslib": "^2.4.0"
|
||||
@@ -20607,7 +22009,6 @@
|
||||
"version": "0.5.4",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.4.tgz",
|
||||
"integrity": "sha512-zTwEpWOzZ2CiKcB93BLngUX59hQkuZjT2+SAQEscSm52peDW/getsawMcWF1rGRpMCX6D7nSJA3CzJ8gn13N/g==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
@@ -21371,6 +22772,15 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/resolve.exports": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz",
|
||||
"integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/restore-cursor": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
|
||||
@@ -22699,9 +24109,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/source-map-js": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
||||
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
|
||||
"integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
@@ -23867,6 +25277,17 @@
|
||||
"cheerio": "0.22.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-api-utils": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz",
|
||||
"integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==",
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=4.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tsconfig-paths": {
|
||||
"version": "3.14.2",
|
||||
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz",
|
||||
@@ -23898,9 +25319,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.5.3",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz",
|
||||
"integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w=="
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
|
||||
},
|
||||
"node_modules/tunnel-agent": {
|
||||
"version": "0.6.0",
|
||||
@@ -24031,16 +25452,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "4.9.5",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
|
||||
"integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
|
||||
"peer": true,
|
||||
"version": "5.4.5",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
|
||||
"integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.2.0"
|
||||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/unbox-primitive": {
|
||||
@@ -24085,6 +25505,19 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/unicode-emoji-utils": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/unicode-emoji-utils/-/unicode-emoji-utils-1.2.0.tgz",
|
||||
"integrity": "sha512-djUB91p/6oYpgps4W5K/MAvM+UspoAANHSUW495BrxeLRoned3iNPEDQgrKx9LbLq93VhNz0NWvI61vcfrwYoA==",
|
||||
"dependencies": {
|
||||
"emoji-regex": "10.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/unicode-emoji-utils/node_modules/emoji-regex": {
|
||||
"version": "10.3.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz",
|
||||
"integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw=="
|
||||
},
|
||||
"node_modules/unicode-match-property-ecmascript": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz",
|
||||
@@ -24541,7 +25974,6 @@
|
||||
"version": "9.2.0",
|
||||
"resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz",
|
||||
"integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/trace-mapping": "^0.3.12",
|
||||
@@ -24556,7 +25988,6 @@
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
|
||||
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
|
||||
"dev": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/validate-npm-package-license": {
|
||||
@@ -25042,11 +26473,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/webpack-merge": {
|
||||
"version": "5.9.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.9.0.tgz",
|
||||
"integrity": "sha512-6NbRQw4+Sy50vYNTw7EyOn41OZItPiXB8GNv3INSoe3PSFaHJEz3SHTrYVaRm2LilNGnFUzh0FAwqPEmU/CwDg==",
|
||||
"version": "5.10.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz",
|
||||
"integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==",
|
||||
"dependencies": {
|
||||
"clone-deep": "^4.0.1",
|
||||
"flat": "^5.0.2",
|
||||
"wildcard": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
@@ -25370,7 +26802,6 @@
|
||||
"version": "17.7.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
|
||||
"integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"cliui": "^8.0.1",
|
||||
"escalade": "^3.1.1",
|
||||
@@ -25388,7 +26819,6 @@
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
||||
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
@@ -25396,14 +26826,12 @@
|
||||
"node_modules/yargs/node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||
"dev": true
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
},
|
||||
"node_modules/yargs/node_modules/is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -25412,7 +26840,6 @@
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
|
||||
12
package.json
12
package.json
@@ -15,6 +15,7 @@
|
||||
"lint": "fedx-scripts eslint --ext .js --ext .jsx .",
|
||||
"lint:fix": "fedx-scripts eslint --fix --ext .js --ext .jsx .",
|
||||
"prepare": "husky install",
|
||||
"postinstall": "patch-package",
|
||||
"snapshot": "fedx-scripts jest --updateSnapshot",
|
||||
"start": "fedx-scripts webpack-dev-server --progress",
|
||||
"test": "fedx-scripts jest --coverage --passWithNoTests"
|
||||
@@ -30,10 +31,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@edx/brand": "npm:@openedx/brand-openedx@^1.2.2",
|
||||
"@edx/frontend-component-footer": "^13.0.4",
|
||||
"@edx/frontend-component-header": "^5.0.2",
|
||||
"@edx/frontend-lib-learning-assistant": "^2.0.0",
|
||||
"@edx/frontend-lib-special-exams": "^3.0.0",
|
||||
"@edx/frontend-lib-special-exams": "^3.0.1",
|
||||
"@edx/frontend-platform": "^7.1.2",
|
||||
"@edx/openedx-atlas": "^0.6.0",
|
||||
"@edx/react-unit-test-utils": "^2.0.0",
|
||||
@@ -42,8 +42,9 @@
|
||||
"@fortawesome/free-regular-svg-icons": "5.15.4",
|
||||
"@fortawesome/free-solid-svg-icons": "5.15.4",
|
||||
"@fortawesome/react-fontawesome": "^0.1.4",
|
||||
"@openedx/frontend-plugin-framework": "^1.0.2",
|
||||
"@openedx/paragon": "^22.1.1",
|
||||
"@openedx/frontend-plugin-framework": "^1.1.2",
|
||||
"@openedx/frontend-slot-footer": "^1.0.2",
|
||||
"@openedx/paragon": "^22.3.0",
|
||||
"@popperjs/core": "2.11.8",
|
||||
"@reduxjs/toolkit": "1.8.1",
|
||||
"classnames": "2.3.2",
|
||||
@@ -70,7 +71,7 @@
|
||||
"devDependencies": {
|
||||
"@edx/browserslist-config": "1.2.0",
|
||||
"@edx/reactifex": "2.2.0",
|
||||
"@openedx/frontend-build": "13.0.28",
|
||||
"@openedx/frontend-build": "13.1.4",
|
||||
"@pact-foundation/pact": "^11.0.2",
|
||||
"@testing-library/jest-dom": "5.16.5",
|
||||
"@testing-library/react": "12.1.5",
|
||||
@@ -84,6 +85,7 @@
|
||||
"jest": "^26.6.3",
|
||||
"jest-console-group-reporter": "^1.0.1",
|
||||
"jest-when": "^3.6.0",
|
||||
"patch-package": "^8.0.0",
|
||||
"postcss-loader": "^8.1.1",
|
||||
"rosie": "2.1.1",
|
||||
"sass": "^1.72.0",
|
||||
|
||||
36
patches/@openedx+frontend-build+13.0.30.patch
Normal file
36
patches/@openedx+frontend-build+13.0.30.patch
Normal file
@@ -0,0 +1,36 @@
|
||||
diff --git a/node_modules/@openedx/frontend-build/config/webpack.prod.config.js b/node_modules/@openedx/frontend-build/config/webpack.prod.config.js
|
||||
index 2879dd9..9efd0fc 100644
|
||||
--- a/node_modules/@openedx/frontend-build/config/webpack.prod.config.js
|
||||
+++ b/node_modules/@openedx/frontend-build/config/webpack.prod.config.js
|
||||
@@ -12,6 +12,7 @@ const NewRelicSourceMapPlugin = require('@edx/new-relic-source-map-webpack-plugi
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
const path = require('path');
|
||||
+const fs = require('fs');
|
||||
const PostCssAutoprefixerPlugin = require('autoprefixer');
|
||||
const PostCssRTLCSS = require('postcss-rtlcss');
|
||||
const PostCssCustomMediaCSS = require('postcss-custom-media');
|
||||
@@ -23,6 +24,23 @@ const HtmlWebpackNewRelicPlugin = require('../lib/plugins/html-webpack-new-relic
|
||||
const commonConfig = require('./webpack.common.config');
|
||||
const presets = require('../lib/presets');
|
||||
|
||||
+/**
|
||||
+ * This condition confirms whether the configuration for the MFE has switched to a JS-based configuration
|
||||
+ * as previously implemented in frontend-build and frontend-platform. If the environment variable JS_CONFIG_FILEPATH
|
||||
+ * exists, then an env.config.js(x) file will be copied from the location referenced by the environment variable to the
|
||||
+ * root directory. Its env variables can be accessed with getConfig().
|
||||
+ *
|
||||
+ * https://github.com/openedx/frontend-build/blob/master/docs/0002-js-environment-config.md
|
||||
+ * https://github.com/openedx/frontend-platform/blob/master/docs/decisions/0007-javascript-file-configuration.rst
|
||||
+ */
|
||||
+
|
||||
+const envConfigPath = process.env.JS_CONFIG_FILEPATH;
|
||||
+
|
||||
+if (envConfigPath) {
|
||||
+ const envConfigFilename = envConfigPath.slice(envConfigPath.indexOf('env.config'));
|
||||
+ fs.copyFileSync(envConfigPath, envConfigFilename);
|
||||
+}
|
||||
+
|
||||
// Add process env vars. Currently used only for setting the PUBLIC_PATH.
|
||||
dotenv.config({
|
||||
path: path.resolve(process.cwd(), '.env'),
|
||||
@@ -1,17 +0,0 @@
|
||||
## How to develop plugin
|
||||
|
||||
You can define plugin in `env.config.jsx` see `example.env.config.jsx` as example.
|
||||
|
||||
## Current caveat
|
||||
|
||||
- The way for how I deal with override method is still wonky
|
||||
- The redux still require middleware to ignore the plugin's action from serializing
|
||||
- I am not sure how it behave with useCallback, useMemo, ...etc
|
||||
- There are still open question on how to write it properly
|
||||
|
||||
## Current work that should consider core part and extendable for the future plugin framework
|
||||
|
||||
- `usePluingsCallback` is the callback supose to be some level of equality to be using `React.useCallback`. It would try to execute the function, then any plugin that try `registerOverrideMethod`. The order of the it being run isn't the determined. There are a couple things I want to add:
|
||||
- I might consider testing it with `zustand` library to make sure it is portable and not rely on `redux`. I tried to do this with provider, but it seems to run into infinite loop of trigger changed.
|
||||
|
||||
- `registerOverrideMethod` is working like a way to register callback that behave like a middleware. It ran the default one, then pass the result of the default one to the plugin. Any plugin that register the override can update the value. Alternatively, we can override the function completely instead applying each affect. Or we can support both. But it requires a bit more thought out architecture.
|
||||
@@ -1,15 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<UnitTranslationPlugin /> render TranslationSelection when translation is enabled and language is available 1`] = `
|
||||
<TranslationSelection
|
||||
availableLanguages={
|
||||
Array [
|
||||
"en",
|
||||
]
|
||||
}
|
||||
courseId="courseId"
|
||||
id="id"
|
||||
language="en"
|
||||
unitId="unitId"
|
||||
/>
|
||||
`;
|
||||
@@ -1,90 +0,0 @@
|
||||
import { getConfig, camelCaseObject } from '@edx/frontend-platform';
|
||||
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
|
||||
import { logError } from '@edx/frontend-platform/logging';
|
||||
import { stringify } from 'query-string';
|
||||
|
||||
export const fetchTranslationConfig = async (courseId) => {
|
||||
const url = `${
|
||||
getConfig().LMS_BASE_URL
|
||||
}/api/translatable_xblocks/config/?course_id=${encodeURIComponent(courseId)}`;
|
||||
try {
|
||||
const { data } = await getAuthenticatedHttpClient().get(url);
|
||||
return {
|
||||
enabled: data.feature_enabled,
|
||||
availableLanguages: data.available_translation_languages || [
|
||||
{
|
||||
code: 'en',
|
||||
label: 'English',
|
||||
},
|
||||
{
|
||||
code: 'es',
|
||||
label: 'Spanish',
|
||||
},
|
||||
],
|
||||
};
|
||||
} catch (error) {
|
||||
logError(`Translation plugin fail to fetch from ${url}`, error);
|
||||
return {
|
||||
enabled: false,
|
||||
availableLanguages: [],
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export async function getTranslationFeedback({
|
||||
courseId,
|
||||
translationLanguage,
|
||||
unitId,
|
||||
userId,
|
||||
}) {
|
||||
const params = stringify({
|
||||
translation_language: translationLanguage,
|
||||
course_id: encodeURIComponent(courseId),
|
||||
unit_id: encodeURIComponent(unitId),
|
||||
user_id: userId,
|
||||
});
|
||||
const fetchFeedbackUrl = `${
|
||||
getConfig().AI_TRANSLATIONS_URL
|
||||
}/api/v1/whole-course-translation-feedback?${params}`;
|
||||
try {
|
||||
const { data } = await getAuthenticatedHttpClient().get(fetchFeedbackUrl);
|
||||
return camelCaseObject(data);
|
||||
} catch (error) {
|
||||
logError(
|
||||
`Translation plugin fail to fetch from ${fetchFeedbackUrl}`,
|
||||
error,
|
||||
);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
export async function createTranslationFeedback({
|
||||
courseId,
|
||||
feedbackValue,
|
||||
translationLanguage,
|
||||
unitId,
|
||||
userId,
|
||||
}) {
|
||||
const createFeedbackUrl = `${
|
||||
getConfig().AI_TRANSLATIONS_URL
|
||||
}/api/v1/whole-course-translation-feedback/`;
|
||||
try {
|
||||
const { data } = await getAuthenticatedHttpClient().post(
|
||||
createFeedbackUrl,
|
||||
{
|
||||
course_id: courseId,
|
||||
feedback_value: feedbackValue,
|
||||
translation_language: translationLanguage,
|
||||
unit_id: unitId,
|
||||
user_id: userId,
|
||||
},
|
||||
);
|
||||
return camelCaseObject(data);
|
||||
} catch (error) {
|
||||
logError(
|
||||
`Translation plugin fail to create feedback from ${createFeedbackUrl}`,
|
||||
error,
|
||||
);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
import { camelCaseObject } from '@edx/frontend-platform';
|
||||
import { logError } from '@edx/frontend-platform/logging';
|
||||
import { stringify } from 'query-string';
|
||||
|
||||
import {
|
||||
fetchTranslationConfig,
|
||||
getTranslationFeedback,
|
||||
createTranslationFeedback,
|
||||
} from './api';
|
||||
|
||||
const mockGetMethod = jest.fn();
|
||||
const mockPostMethod = jest.fn();
|
||||
jest.mock('@edx/frontend-platform/auth', () => ({
|
||||
getAuthenticatedHttpClient: () => ({
|
||||
get: mockGetMethod,
|
||||
post: mockPostMethod,
|
||||
}),
|
||||
}));
|
||||
jest.mock('@edx/frontend-platform/logging', () => ({
|
||||
logError: jest.fn(),
|
||||
}));
|
||||
|
||||
describe('UnitTranslation api', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
describe('fetchTranslationConfig', () => {
|
||||
const courseId = 'course-v1:edX+DemoX+Demo_Course';
|
||||
const expectedResponse = {
|
||||
feature_enabled: true,
|
||||
available_translation_languages: [
|
||||
{
|
||||
code: 'en',
|
||||
label: 'English',
|
||||
},
|
||||
{
|
||||
code: 'es',
|
||||
label: 'Spanish',
|
||||
},
|
||||
],
|
||||
};
|
||||
it('should fetch translation config', async () => {
|
||||
const expectedUrl = `http://localhost:18000/api/translatable_xblocks/config/?course_id=${encodeURIComponent(
|
||||
courseId,
|
||||
)}`;
|
||||
mockGetMethod.mockResolvedValueOnce({ data: expectedResponse });
|
||||
const result = await fetchTranslationConfig(courseId);
|
||||
expect(result).toEqual({
|
||||
enabled: true,
|
||||
availableLanguages: expectedResponse.available_translation_languages,
|
||||
});
|
||||
expect(mockGetMethod).toHaveBeenCalledWith(expectedUrl);
|
||||
});
|
||||
|
||||
it('should return disabled and unavailable languages on error', async () => {
|
||||
mockGetMethod.mockRejectedValueOnce(new Error('error'));
|
||||
const result = await fetchTranslationConfig(courseId);
|
||||
expect(result).toEqual({
|
||||
enabled: false,
|
||||
availableLanguages: [],
|
||||
});
|
||||
expect(logError).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('getTranslationFeedback', () => {
|
||||
const props = {
|
||||
courseId: 'course-v1:edX+DemoX+Demo_Course',
|
||||
translationLanguage: 'es',
|
||||
unitId: 'unit-v1:edX+DemoX+Demo_Course+type@video+block@video',
|
||||
userId: 'test_user',
|
||||
};
|
||||
const expectedResponse = {
|
||||
feedback: 'good',
|
||||
};
|
||||
it('should fetch translation feedback', async () => {
|
||||
const params = stringify({
|
||||
translation_language: props.translationLanguage,
|
||||
course_id: encodeURIComponent(props.courseId),
|
||||
unit_id: encodeURIComponent(props.unitId),
|
||||
user_id: props.userId,
|
||||
});
|
||||
const expectedUrl = `http://localhost:18760/api/v1/whole-course-translation-feedback?${params}`;
|
||||
mockGetMethod.mockResolvedValueOnce({ data: expectedResponse });
|
||||
const result = await getTranslationFeedback(props);
|
||||
expect(result).toEqual(camelCaseObject(expectedResponse));
|
||||
expect(mockGetMethod).toHaveBeenCalledWith(expectedUrl);
|
||||
});
|
||||
|
||||
it('should return empty object on error', async () => {
|
||||
mockGetMethod.mockRejectedValueOnce(new Error('error'));
|
||||
const result = await getTranslationFeedback(props);
|
||||
expect(result).toEqual({});
|
||||
expect(logError).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('createTranslationFeedback', () => {
|
||||
const props = {
|
||||
courseId: 'course-v1:edX+DemoX+Demo_Course',
|
||||
feedbackValue: 'good',
|
||||
translationLanguage: 'es',
|
||||
unitId: 'unit-v1:edX+DemoX+Demo_Course+type@video+block@video',
|
||||
userId: 'test_user',
|
||||
};
|
||||
it('should create translation feedback', async () => {
|
||||
const expectedUrl = 'http://localhost:18760/api/v1/whole-course-translation-feedback/';
|
||||
mockPostMethod.mockResolvedValueOnce({});
|
||||
await createTranslationFeedback(props);
|
||||
expect(mockPostMethod).toHaveBeenCalledWith(expectedUrl, {
|
||||
course_id: props.courseId,
|
||||
feedback_value: props.feedbackValue,
|
||||
translation_language: props.translationLanguage,
|
||||
unit_id: props.unitId,
|
||||
user_id: props.userId,
|
||||
});
|
||||
});
|
||||
|
||||
it('should log error on failure', async () => {
|
||||
mockPostMethod.mockRejectedValueOnce(new Error('error'));
|
||||
await createTranslationFeedback(props);
|
||||
expect(logError).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,204 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<FeedbackWidget /> render feedback widget 1`] = `
|
||||
<div
|
||||
className="d-none"
|
||||
>
|
||||
<div
|
||||
className="sequence w-100"
|
||||
>
|
||||
<div
|
||||
className="ml-4 mr-2"
|
||||
>
|
||||
<ActionRow>
|
||||
Rate this page translation
|
||||
<Spacer />
|
||||
<div>
|
||||
<IconButton
|
||||
alt="positive-feedback"
|
||||
className="m-1"
|
||||
iconAs="Icon"
|
||||
id="positive-feedback-button"
|
||||
onClick={[MockFunction onThumbsUpClick]}
|
||||
src="ThumbUpOutline"
|
||||
variant="secondary"
|
||||
/>
|
||||
<IconButton
|
||||
alt="negative-feedback"
|
||||
className="mr-2"
|
||||
iconAs="Icon"
|
||||
id="negative-feedback-button"
|
||||
onClick={[MockFunction onThumbsDownClick]}
|
||||
src="ThumbDownOffAlt"
|
||||
variant="secondary"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="mb-1 text-light action-row-divider"
|
||||
>
|
||||
|
|
||||
</div>
|
||||
<div>
|
||||
<IconButton
|
||||
alt="close-feedback"
|
||||
className="ml-1 mr-2 float-right"
|
||||
iconAs="Icon"
|
||||
id="close-feedback-button"
|
||||
onClick={[MockFunction closeFeedbackWidget]}
|
||||
src="Close"
|
||||
variant="secondary"
|
||||
/>
|
||||
</div>
|
||||
</ActionRow>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`<FeedbackWidget /> render gratitude text 1`] = `
|
||||
<div
|
||||
className="d-none"
|
||||
>
|
||||
<div
|
||||
className="sequence w-100"
|
||||
>
|
||||
<div
|
||||
className="ml-4 mr-4"
|
||||
>
|
||||
<ActionRow
|
||||
className="m-2 justify-content-center"
|
||||
>
|
||||
Thank you! Your feedback matters.
|
||||
</ActionRow>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`<FeedbackWidget /> renders hidden by default 1`] = `
|
||||
<div
|
||||
className="d-none"
|
||||
>
|
||||
<div
|
||||
className="sequence w-100"
|
||||
>
|
||||
<div
|
||||
className="ml-4 mr-2"
|
||||
>
|
||||
<ActionRow>
|
||||
Rate this page translation
|
||||
<Spacer />
|
||||
<div>
|
||||
<IconButton
|
||||
alt="positive-feedback"
|
||||
className="m-1"
|
||||
iconAs="Icon"
|
||||
id="positive-feedback-button"
|
||||
onClick={[MockFunction onThumbsUpClick]}
|
||||
src="ThumbUpOutline"
|
||||
variant="secondary"
|
||||
/>
|
||||
<IconButton
|
||||
alt="negative-feedback"
|
||||
className="mr-2"
|
||||
iconAs="Icon"
|
||||
id="negative-feedback-button"
|
||||
onClick={[MockFunction onThumbsDownClick]}
|
||||
src="ThumbDownOffAlt"
|
||||
variant="secondary"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="mb-1 text-light action-row-divider"
|
||||
>
|
||||
|
|
||||
</div>
|
||||
<div>
|
||||
<IconButton
|
||||
alt="close-feedback"
|
||||
className="ml-1 mr-2 float-right"
|
||||
iconAs="Icon"
|
||||
id="close-feedback-button"
|
||||
onClick={[MockFunction closeFeedbackWidget]}
|
||||
src="Close"
|
||||
variant="secondary"
|
||||
/>
|
||||
</div>
|
||||
</ActionRow>
|
||||
</div>
|
||||
<div
|
||||
className="ml-4 mr-4"
|
||||
>
|
||||
<ActionRow
|
||||
className="m-2 justify-content-center"
|
||||
>
|
||||
Thank you! Your feedback matters.
|
||||
</ActionRow>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`<FeedbackWidget /> renders show when elemReady is true 1`] = `
|
||||
<div
|
||||
className="sequence-container d-inline-flex flex-row w-100"
|
||||
>
|
||||
<div
|
||||
className="sequence w-100"
|
||||
>
|
||||
<div
|
||||
className="ml-4 mr-2"
|
||||
>
|
||||
<ActionRow>
|
||||
Rate this page translation
|
||||
<Spacer />
|
||||
<div>
|
||||
<IconButton
|
||||
alt="positive-feedback"
|
||||
className="m-1"
|
||||
iconAs="Icon"
|
||||
id="positive-feedback-button"
|
||||
onClick={[MockFunction onThumbsUpClick]}
|
||||
src="ThumbUpOutline"
|
||||
variant="secondary"
|
||||
/>
|
||||
<IconButton
|
||||
alt="negative-feedback"
|
||||
className="mr-2"
|
||||
iconAs="Icon"
|
||||
id="negative-feedback-button"
|
||||
onClick={[MockFunction onThumbsDownClick]}
|
||||
src="ThumbDownOffAlt"
|
||||
variant="secondary"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="mb-1 text-light action-row-divider"
|
||||
>
|
||||
|
|
||||
</div>
|
||||
<div>
|
||||
<IconButton
|
||||
alt="close-feedback"
|
||||
className="ml-1 mr-2 float-right"
|
||||
iconAs="Icon"
|
||||
id="close-feedback-button"
|
||||
onClick={[MockFunction closeFeedbackWidget]}
|
||||
src="Close"
|
||||
variant="secondary"
|
||||
/>
|
||||
</div>
|
||||
</ActionRow>
|
||||
</div>
|
||||
<div
|
||||
className="ml-4 mr-4"
|
||||
>
|
||||
<ActionRow
|
||||
className="m-2 justify-content-center"
|
||||
>
|
||||
Thank you! Your feedback matters.
|
||||
</ActionRow>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -1,116 +0,0 @@
|
||||
import React, {
|
||||
useEffect, useRef, useState,
|
||||
} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { useIntl } from '@edx/frontend-platform/i18n';
|
||||
import { ActionRow, IconButton, Icon } from '@openedx/paragon';
|
||||
import { Close, ThumbUpOutline, ThumbDownOffAlt } from '@openedx/paragon/icons';
|
||||
|
||||
import './index.scss';
|
||||
import messages from './messages';
|
||||
import useFeedbackWidget from './useFeedbackWidget';
|
||||
|
||||
const FeedbackWidget = ({
|
||||
courseId,
|
||||
translationLanguage,
|
||||
unitId,
|
||||
userId,
|
||||
}) => {
|
||||
const { formatMessage } = useIntl();
|
||||
const ref = useRef(null);
|
||||
const [elemReady, setElemReady] = useState(false);
|
||||
const {
|
||||
closeFeedbackWidget,
|
||||
showFeedbackWidget,
|
||||
showGratitudeText,
|
||||
onThumbsUpClick,
|
||||
onThumbsDownClick,
|
||||
} = useFeedbackWidget({
|
||||
courseId,
|
||||
translationLanguage,
|
||||
unitId,
|
||||
userId,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (ref.current) {
|
||||
const domNode = document.getElementById('whole-course-translation-feedback-widget');
|
||||
domNode.appendChild(ref.current);
|
||||
setElemReady(true);
|
||||
}
|
||||
}, [ref.current]);
|
||||
|
||||
return (
|
||||
<div ref={ref} className={(elemReady) ? 'sequence-container d-inline-flex flex-row w-100' : 'd-none'}>
|
||||
{(showFeedbackWidget || showGratitudeText) ? (
|
||||
<div className="sequence w-100">
|
||||
{
|
||||
showFeedbackWidget && (
|
||||
<div className="ml-4 mr-2">
|
||||
<ActionRow>
|
||||
{formatMessage(messages.rateTranslationText)}
|
||||
<ActionRow.Spacer />
|
||||
<div>
|
||||
<IconButton
|
||||
src={ThumbUpOutline}
|
||||
iconAs={Icon}
|
||||
alt="positive-feedback"
|
||||
onClick={onThumbsUpClick}
|
||||
variant="secondary"
|
||||
className="m-1"
|
||||
id="positive-feedback-button"
|
||||
/>
|
||||
<IconButton
|
||||
src={ThumbDownOffAlt}
|
||||
iconAs={Icon}
|
||||
alt="negative-feedback"
|
||||
onClick={onThumbsDownClick}
|
||||
variant="secondary"
|
||||
className="mr-2"
|
||||
id="negative-feedback-button"
|
||||
/>
|
||||
</div>
|
||||
<div className="mb-1 text-light action-row-divider">
|
||||
|
|
||||
</div>
|
||||
<div>
|
||||
<IconButton
|
||||
src={Close}
|
||||
iconAs={Icon}
|
||||
alt="close-feedback"
|
||||
onClick={closeFeedbackWidget}
|
||||
variant="secondary"
|
||||
className="ml-1 mr-2 float-right"
|
||||
id="close-feedback-button"
|
||||
/>
|
||||
</div>
|
||||
</ActionRow>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{
|
||||
showGratitudeText && (
|
||||
<div className="ml-4 mr-4">
|
||||
<ActionRow className="m-2 justify-content-center">
|
||||
{formatMessage(messages.gratitudeText)}
|
||||
</ActionRow>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
FeedbackWidget.propTypes = {
|
||||
courseId: PropTypes.string.isRequired,
|
||||
translationLanguage: PropTypes.string.isRequired,
|
||||
userId: PropTypes.string.isRequired,
|
||||
unitId: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
FeedbackWidget.defaultProps = {};
|
||||
|
||||
export default FeedbackWidget;
|
||||
@@ -1,4 +0,0 @@
|
||||
.action-row-divider {
|
||||
font-size: 31px;
|
||||
font-weight: 100;
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
import { useState } from 'react';
|
||||
import { shallow } from '@edx/react-unit-test-utils';
|
||||
|
||||
import FeedbackWidget from './index';
|
||||
import useFeedbackWidget from './useFeedbackWidget';
|
||||
|
||||
jest.mock('react', () => ({
|
||||
...jest.requireActual('react'),
|
||||
useState: jest.fn((value) => [value, jest.fn()]),
|
||||
}));
|
||||
jest.mock('@openedx/paragon', () => jest.requireActual('@edx/react-unit-test-utils').mockComponents({
|
||||
ActionRow: {
|
||||
Spacer: 'Spacer',
|
||||
},
|
||||
IconButton: 'IconButton',
|
||||
Icon: 'Icon',
|
||||
}));
|
||||
jest.mock('@openedx/paragon/icons', () => ({
|
||||
Close: 'Close',
|
||||
ThumbUpOutline: 'ThumbUpOutline',
|
||||
ThumbDownOffAlt: 'ThumbDownOffAlt',
|
||||
}));
|
||||
jest.mock('./useFeedbackWidget');
|
||||
jest.mock('@edx/frontend-platform/i18n', () => {
|
||||
const i18n = jest.requireActual('@edx/frontend-platform/i18n');
|
||||
const { formatMessage } = jest.requireActual('@edx/react-unit-test-utils');
|
||||
return {
|
||||
...i18n,
|
||||
useIntl: jest.fn(() => ({
|
||||
formatMessage,
|
||||
})),
|
||||
};
|
||||
});
|
||||
|
||||
describe('<FeedbackWidget />', () => {
|
||||
const props = {
|
||||
courseId: 'course-v1:edX+DemoX+Demo_Course',
|
||||
translationLanguage: 'es',
|
||||
unitId:
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@37b72b3915204b70acb00c55b604b563',
|
||||
userId: '123',
|
||||
};
|
||||
|
||||
const mockUseFeedbackWidget = ({ showFeedbackWidget, showGratitudeText }) => {
|
||||
useFeedbackWidget.mockReturnValueOnce({
|
||||
closeFeedbackWidget: jest.fn().mockName('closeFeedbackWidget'),
|
||||
sendFeedback: jest.fn().mockName('sendFeedback'),
|
||||
onThumbsUpClick: jest.fn().mockName('onThumbsUpClick'),
|
||||
onThumbsDownClick: jest.fn().mockName('onThumbsDownClick'),
|
||||
showFeedbackWidget,
|
||||
showGratitudeText,
|
||||
});
|
||||
};
|
||||
|
||||
it('renders hidden by default', () => {
|
||||
mockUseFeedbackWidget({
|
||||
showFeedbackWidget: true,
|
||||
showGratitudeText: true,
|
||||
});
|
||||
const wrapper = shallow(<FeedbackWidget {...props} />);
|
||||
expect(wrapper.snapshot).toMatchSnapshot();
|
||||
expect(wrapper.instance.findByType('div')[0].props.className).toContain(
|
||||
'd-none',
|
||||
);
|
||||
});
|
||||
|
||||
it('renders show when elemReady is true', () => {
|
||||
mockUseFeedbackWidget({
|
||||
showFeedbackWidget: true,
|
||||
showGratitudeText: true,
|
||||
});
|
||||
useState.mockReturnValueOnce([true, jest.fn()]);
|
||||
const wrapper = shallow(<FeedbackWidget {...props} />);
|
||||
expect(wrapper.snapshot).toMatchSnapshot();
|
||||
expect(wrapper.instance.findByType('div')[0].props.className).not.toContain(
|
||||
'd-none',
|
||||
);
|
||||
});
|
||||
|
||||
it('render empty when showFeedbackWidget and showGratitudeText are false', () => {
|
||||
mockUseFeedbackWidget({
|
||||
showFeedbackWidget: false,
|
||||
showGratitudeText: false,
|
||||
});
|
||||
useState.mockReturnValueOnce([true, jest.fn()]);
|
||||
const wrapper = shallow(<FeedbackWidget {...props} />);
|
||||
expect(wrapper.instance.findByType('div')[0].children.length).toBe(0);
|
||||
});
|
||||
|
||||
it('render feedback widget', () => {
|
||||
mockUseFeedbackWidget({
|
||||
showFeedbackWidget: true,
|
||||
showGratitudeText: false,
|
||||
});
|
||||
const wrapper = shallow(<FeedbackWidget {...props} />);
|
||||
expect(wrapper.snapshot).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('render gratitude text', () => {
|
||||
mockUseFeedbackWidget({
|
||||
showFeedbackWidget: false,
|
||||
showGratitudeText: true,
|
||||
});
|
||||
const wrapper = shallow(<FeedbackWidget {...props} />);
|
||||
expect(wrapper.snapshot).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
@@ -1,16 +0,0 @@
|
||||
import { defineMessages } from '@edx/frontend-platform/i18n';
|
||||
|
||||
const messages = defineMessages({
|
||||
rateTranslationText: {
|
||||
id: 'feedbackWidget.rateTranslationText',
|
||||
defaultMessage: 'Rate this page translation',
|
||||
description: 'Title for the feedback widget action row.',
|
||||
},
|
||||
gratitudeText: {
|
||||
id: 'feedbackWidget.gratitudeText',
|
||||
defaultMessage: 'Thank you! Your feedback matters.',
|
||||
description: 'Title for secondary action row.',
|
||||
},
|
||||
});
|
||||
|
||||
export default messages;
|
||||
@@ -1,82 +0,0 @@
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
import { createTranslationFeedback, getTranslationFeedback } from '../data/api';
|
||||
|
||||
const useFeedbackWidget = ({
|
||||
courseId,
|
||||
translationLanguage,
|
||||
unitId,
|
||||
userId,
|
||||
}) => {
|
||||
const [showFeedbackWidget, setShowFeedbackWidget] = useState(false);
|
||||
const [showGratitudeText, setShowGratitudeText] = useState(false);
|
||||
|
||||
const closeFeedbackWidget = useCallback(() => {
|
||||
setShowFeedbackWidget(false);
|
||||
}, [setShowFeedbackWidget]);
|
||||
|
||||
const openFeedbackWidget = useCallback(() => {
|
||||
setShowFeedbackWidget(true);
|
||||
}, [setShowFeedbackWidget]);
|
||||
|
||||
useEffect(async () => {
|
||||
const translationFeedback = await getTranslationFeedback({
|
||||
courseId,
|
||||
translationLanguage,
|
||||
unitId,
|
||||
userId,
|
||||
});
|
||||
setShowFeedbackWidget(!translationFeedback);
|
||||
}, [
|
||||
courseId,
|
||||
translationLanguage,
|
||||
unitId,
|
||||
userId,
|
||||
]);
|
||||
|
||||
const openGratitudeText = useCallback(() => {
|
||||
setShowGratitudeText(true);
|
||||
setTimeout(() => {
|
||||
setShowGratitudeText(false);
|
||||
}, 3000);
|
||||
}, [setShowGratitudeText]);
|
||||
|
||||
const sendFeedback = useCallback(async (feedbackValue) => {
|
||||
await createTranslationFeedback({
|
||||
courseId,
|
||||
feedbackValue,
|
||||
translationLanguage,
|
||||
unitId,
|
||||
userId,
|
||||
});
|
||||
closeFeedbackWidget();
|
||||
openGratitudeText();
|
||||
}, [
|
||||
courseId,
|
||||
translationLanguage,
|
||||
unitId,
|
||||
userId,
|
||||
closeFeedbackWidget,
|
||||
openGratitudeText,
|
||||
]);
|
||||
|
||||
const onThumbsUpClick = useCallback(() => {
|
||||
sendFeedback(true);
|
||||
}, [sendFeedback]);
|
||||
const onThumbsDownClick = useCallback(() => {
|
||||
sendFeedback(false);
|
||||
}, [sendFeedback]);
|
||||
|
||||
return {
|
||||
closeFeedbackWidget,
|
||||
openFeedbackWidget,
|
||||
openGratitudeText,
|
||||
sendFeedback,
|
||||
showFeedbackWidget,
|
||||
showGratitudeText,
|
||||
onThumbsUpClick,
|
||||
onThumbsDownClick,
|
||||
};
|
||||
};
|
||||
|
||||
export default useFeedbackWidget;
|
||||
@@ -1,163 +0,0 @@
|
||||
import { renderHook, act } from '@testing-library/react-hooks';
|
||||
|
||||
import useFeedbackWidget from './useFeedbackWidget';
|
||||
import { createTranslationFeedback, getTranslationFeedback } from '../data/api';
|
||||
|
||||
jest.mock('../data/api', () => ({
|
||||
createTranslationFeedback: jest.fn(),
|
||||
getTranslationFeedback: jest.fn(),
|
||||
}));
|
||||
|
||||
const initialProps = {
|
||||
courseId: 'course-v1:edX+DemoX+Demo_Course',
|
||||
translationLanguage: 'es',
|
||||
unitId: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_0270f6de40fc',
|
||||
userId: 3,
|
||||
};
|
||||
|
||||
const newProps = {
|
||||
courseId: 'course-v1:edX+DemoX+Demo_Course',
|
||||
translationLanguage: 'fr',
|
||||
unitId: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_0270f6de40fc',
|
||||
userId: 3,
|
||||
};
|
||||
|
||||
describe('useFeedbackWidget', () => {
|
||||
beforeEach(async () => {
|
||||
getTranslationFeedback.mockReturnValue('');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
test('closeFeedbackWidget behavior', () => {
|
||||
const { result, waitFor } = renderHook(() => useFeedbackWidget(initialProps));
|
||||
waitFor(() => expect(result.current.showFeedbackWidget.toBe(true)));
|
||||
act(() => {
|
||||
result.current.closeFeedbackWidget();
|
||||
});
|
||||
expect(result.current.showFeedbackWidget).toBe(false);
|
||||
});
|
||||
|
||||
test('openFeedbackWidget behavior', () => {
|
||||
const { result } = renderHook(() => useFeedbackWidget(initialProps));
|
||||
act(() => {
|
||||
result.current.closeFeedbackWidget();
|
||||
});
|
||||
expect(result.current.showFeedbackWidget).toBe(false);
|
||||
act(() => {
|
||||
result.current.openFeedbackWidget();
|
||||
});
|
||||
expect(result.current.showFeedbackWidget).toBe(true);
|
||||
});
|
||||
|
||||
test('openGratitudeText behavior', async () => {
|
||||
const { result, waitFor } = renderHook(() => useFeedbackWidget(initialProps));
|
||||
|
||||
expect(result.current.showGratitudeText).toBe(false);
|
||||
act(() => {
|
||||
result.current.openGratitudeText();
|
||||
});
|
||||
expect(result.current.showGratitudeText).toBe(true);
|
||||
// Wait for 3 seconds to hide the gratitude text
|
||||
waitFor(() => {
|
||||
expect(result.current.showGratitudeText).toBe(false);
|
||||
}, { timeout: 3000 });
|
||||
});
|
||||
|
||||
test('sendFeedback behavior', () => {
|
||||
const { result, waitFor } = renderHook(() => useFeedbackWidget(initialProps));
|
||||
const feedbackValue = true;
|
||||
|
||||
waitFor(() => expect(result.current.showFeedbackWidget.toBe(true)));
|
||||
|
||||
expect(result.current.showGratitudeText).toBe(false);
|
||||
act(() => {
|
||||
result.current.sendFeedback(feedbackValue);
|
||||
});
|
||||
|
||||
waitFor(() => {
|
||||
expect(result.current.showFeedbackWidget).toBe(false);
|
||||
expect(result.current.showGratitudeText).toBe(true);
|
||||
});
|
||||
|
||||
expect(createTranslationFeedback).toHaveBeenCalledWith({
|
||||
courseId: initialProps.courseId,
|
||||
feedbackValue,
|
||||
translationLanguage: initialProps.translationLanguage,
|
||||
unitId: initialProps.unitId,
|
||||
userId: initialProps.userId,
|
||||
});
|
||||
|
||||
// Wait for 3 seconds to hide the gratitude text
|
||||
waitFor(() => {
|
||||
expect(result.current.showGratitudeText).toBe(false);
|
||||
}, { timeout: 3000 });
|
||||
});
|
||||
|
||||
test('onThumbsUpClick behavior', () => {
|
||||
const { result } = renderHook(() => useFeedbackWidget(initialProps));
|
||||
|
||||
act(() => {
|
||||
result.current.onThumbsUpClick();
|
||||
});
|
||||
|
||||
expect(createTranslationFeedback).toHaveBeenCalledWith({
|
||||
courseId: initialProps.courseId,
|
||||
feedbackValue: true,
|
||||
translationLanguage: initialProps.translationLanguage,
|
||||
unitId: initialProps.unitId,
|
||||
userId: initialProps.userId,
|
||||
});
|
||||
});
|
||||
|
||||
test('onThumbsDownClick behavior', () => {
|
||||
const { result } = renderHook(() => useFeedbackWidget(initialProps));
|
||||
|
||||
act(() => {
|
||||
result.current.onThumbsDownClick();
|
||||
});
|
||||
|
||||
expect(createTranslationFeedback).toHaveBeenCalledWith({
|
||||
courseId: initialProps.courseId,
|
||||
feedbackValue: false,
|
||||
translationLanguage: initialProps.translationLanguage,
|
||||
unitId: initialProps.unitId,
|
||||
userId: initialProps.userId,
|
||||
});
|
||||
});
|
||||
|
||||
test('fetch feedback on initialization', () => {
|
||||
const { waitFor } = renderHook(() => useFeedbackWidget(initialProps));
|
||||
waitFor(() => {
|
||||
expect(getTranslationFeedback).toHaveBeenCalledWith({
|
||||
courseId: initialProps.courseId,
|
||||
translationLanguage: initialProps.translationLanguage,
|
||||
unitId: initialProps.unitId,
|
||||
userId: initialProps.userId,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('fetch feedback on props update', () => {
|
||||
const { rerender, waitFor } = renderHook(() => useFeedbackWidget(initialProps));
|
||||
waitFor(() => {
|
||||
expect(getTranslationFeedback).toHaveBeenCalledWith({
|
||||
courseId: initialProps.courseId,
|
||||
translationLanguage: initialProps.translationLanguage,
|
||||
unitId: initialProps.unitId,
|
||||
userId: initialProps.userId,
|
||||
});
|
||||
});
|
||||
rerender(newProps);
|
||||
waitFor(() => {
|
||||
expect(getTranslationFeedback).toHaveBeenCalledWith({
|
||||
courseId: newProps.courseId,
|
||||
translationLanguage: newProps.translationLanguage,
|
||||
unitId: newProps.unitId,
|
||||
userId: newProps.userId,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,43 +0,0 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { useModel } from '@src/generic/model-store';
|
||||
|
||||
import TranslationSelection from './translation-selection';
|
||||
import { fetchTranslationConfig } from './data/api';
|
||||
|
||||
const UnitTranslationPlugin = ({ id, courseId, unitId }) => {
|
||||
const { language } = useModel('coursewareMeta', courseId);
|
||||
const [translationConfig, setTranslationConfig] = useState({
|
||||
enabled: false,
|
||||
availableLanguages: [],
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
fetchTranslationConfig(courseId).then(setTranslationConfig);
|
||||
}, []);
|
||||
|
||||
const { enabled, availableLanguages } = translationConfig;
|
||||
|
||||
if (!enabled || !language || !availableLanguages.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<TranslationSelection
|
||||
id={id}
|
||||
courseId={courseId}
|
||||
language={language}
|
||||
availableLanguages={availableLanguages}
|
||||
unitId={unitId}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
UnitTranslationPlugin.propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
courseId: PropTypes.string.isRequired,
|
||||
unitId: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default UnitTranslationPlugin;
|
||||
@@ -1,62 +0,0 @@
|
||||
import { shallow } from '@edx/react-unit-test-utils';
|
||||
import { useState } from 'react';
|
||||
import { useModel } from '@src/generic/model-store';
|
||||
|
||||
import UnitTranslationPlugin from './index';
|
||||
|
||||
jest.mock('@src/generic/model-store');
|
||||
jest.mock('./data/api', () => ({
|
||||
fetchTranslationConfig: jest.fn(),
|
||||
}));
|
||||
jest.mock('./translation-selection', () => 'TranslationSelection');
|
||||
jest.mock('react', () => ({
|
||||
...jest.requireActual('react'),
|
||||
useState: jest.fn(),
|
||||
}));
|
||||
|
||||
describe('<UnitTranslationPlugin />', () => {
|
||||
const props = {
|
||||
id: 'id',
|
||||
courseId: 'courseId',
|
||||
unitId: 'unitId',
|
||||
};
|
||||
const mockInitialState = ({ enabled = true, availableLanguages = ['en'] }) => {
|
||||
useState.mockReturnValue([{ enabled, availableLanguages }, jest.fn()]);
|
||||
};
|
||||
it('render empty when translation is not enabled', () => {
|
||||
useModel.mockReturnValue({ language: 'en' });
|
||||
mockInitialState({ enabled: false });
|
||||
|
||||
const wrapper = shallow(<UnitTranslationPlugin {...props} />);
|
||||
|
||||
expect(wrapper.isEmptyRender()).toBe(true);
|
||||
});
|
||||
it('render empty when available languages is empty', () => {
|
||||
useModel.mockReturnValue({ language: 'fr' });
|
||||
mockInitialState({
|
||||
availableLanguages: [],
|
||||
});
|
||||
|
||||
const wrapper = shallow(<UnitTranslationPlugin {...props} />);
|
||||
|
||||
expect(wrapper.isEmptyRender()).toBe(true);
|
||||
});
|
||||
|
||||
it('render empty when course language has not been set', () => {
|
||||
useModel.mockReturnValue({ language: undefined });
|
||||
mockInitialState({});
|
||||
|
||||
const wrapper = shallow(<UnitTranslationPlugin {...props} />);
|
||||
|
||||
expect(wrapper.isEmptyRender()).toBe(true);
|
||||
});
|
||||
|
||||
it('render TranslationSelection when translation is enabled and language is available', () => {
|
||||
useModel.mockReturnValue({ language: 'en' });
|
||||
mockInitialState({});
|
||||
|
||||
const wrapper = shallow(<UnitTranslationPlugin {...props} />);
|
||||
|
||||
expect(wrapper.snapshot).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
@@ -1,82 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { useIntl } from '@edx/frontend-platform/i18n';
|
||||
import {
|
||||
StandardModal,
|
||||
ActionRow,
|
||||
Button,
|
||||
Icon,
|
||||
ListBox,
|
||||
ListBoxOption,
|
||||
} from '@openedx/paragon';
|
||||
import { Check } from '@openedx/paragon/icons';
|
||||
|
||||
import useTranslationModal from './useTranslationModal';
|
||||
import messages from './messages';
|
||||
|
||||
import './TranslationModal.scss';
|
||||
|
||||
const TranslationModal = ({
|
||||
isOpen,
|
||||
close,
|
||||
selectedLanguage,
|
||||
setSelectedLanguage,
|
||||
availableLanguages,
|
||||
}) => {
|
||||
const { formatMessage } = useIntl();
|
||||
const { selectedIndex, setSelectedIndex, onSubmit } = useTranslationModal({
|
||||
selectedLanguage,
|
||||
setSelectedLanguage,
|
||||
close,
|
||||
availableLanguages,
|
||||
});
|
||||
|
||||
return (
|
||||
<StandardModal
|
||||
title={formatMessage(messages.languageSelectionModalTitle)}
|
||||
isOpen={isOpen}
|
||||
onClose={close}
|
||||
footerNode={(
|
||||
<ActionRow>
|
||||
<ActionRow.Spacer />
|
||||
<Button variant="tertiary" onClick={close}>
|
||||
{formatMessage(messages.cancelButtonText)}
|
||||
</Button>
|
||||
<Button onClick={onSubmit}>
|
||||
{formatMessage(messages.submitButtonText)}
|
||||
</Button>
|
||||
</ActionRow>
|
||||
)}
|
||||
>
|
||||
<ListBox className="listbox-container">
|
||||
{availableLanguages.map(({ code, label }, index) => (
|
||||
<ListBoxOption
|
||||
className="d-flex justify-content-between"
|
||||
key={code}
|
||||
selectedOptionIndex={selectedIndex}
|
||||
onSelect={() => setSelectedIndex(index)}
|
||||
>
|
||||
{label}
|
||||
{selectedIndex === index && <Icon src={Check} />}
|
||||
</ListBoxOption>
|
||||
))}
|
||||
</ListBox>
|
||||
</StandardModal>
|
||||
);
|
||||
};
|
||||
|
||||
TranslationModal.propTypes = {
|
||||
isOpen: PropTypes.bool.isRequired,
|
||||
close: PropTypes.func.isRequired,
|
||||
selectedLanguage: PropTypes.string.isRequired,
|
||||
setSelectedLanguage: PropTypes.func.isRequired,
|
||||
availableLanguages: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
code: PropTypes.string.isRequired,
|
||||
label: PropTypes.string.isRequired,
|
||||
}),
|
||||
).isRequired,
|
||||
};
|
||||
|
||||
export default TranslationModal;
|
||||
@@ -1,7 +0,0 @@
|
||||
.listbox-container {
|
||||
max-height: 400px;
|
||||
|
||||
:last-child {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
import { shallow } from '@edx/react-unit-test-utils';
|
||||
|
||||
import TranslationModal from './TranslationModal';
|
||||
|
||||
jest.mock('./useTranslationModal', () => ({
|
||||
__esModule: true,
|
||||
default: () => ({
|
||||
selectedIndex: 0,
|
||||
setSelectedIndex: jest.fn(),
|
||||
onSubmit: jest.fn().mockName('onSubmit'),
|
||||
}),
|
||||
}));
|
||||
jest.mock('@openedx/paragon', () => jest.requireActual('@edx/react-unit-test-utils').mockComponents({
|
||||
StandardModal: 'StandardModal',
|
||||
ActionRow: {
|
||||
Spacer: 'Spacer',
|
||||
},
|
||||
Button: 'Button',
|
||||
Icon: 'Icon',
|
||||
ListBox: 'ListBox',
|
||||
ListBoxOption: 'ListBoxOption',
|
||||
}));
|
||||
jest.mock('@openedx/paragon/icons', () => ({
|
||||
Check: jest.fn().mockName('icons.Check'),
|
||||
}));
|
||||
jest.mock('@edx/frontend-platform/i18n', () => {
|
||||
const i18n = jest.requireActual('@edx/frontend-platform/i18n');
|
||||
const { formatMessage } = jest.requireActual('@edx/react-unit-test-utils');
|
||||
return {
|
||||
...i18n,
|
||||
useIntl: jest.fn(() => ({
|
||||
formatMessage,
|
||||
})),
|
||||
};
|
||||
});
|
||||
|
||||
describe('TranslationModal', () => {
|
||||
const props = {
|
||||
isOpen: true,
|
||||
close: jest.fn().mockName('close'),
|
||||
selectedLanguage: 'en',
|
||||
setSelectedLanguage: jest.fn().mockName('setSelectedLanguage'),
|
||||
availableLanguages: [
|
||||
{
|
||||
code: 'en',
|
||||
label: 'English',
|
||||
},
|
||||
{
|
||||
code: 'es',
|
||||
label: 'Spanish',
|
||||
},
|
||||
],
|
||||
};
|
||||
it('renders correctly', () => {
|
||||
const wrapper = shallow(<TranslationModal {...props} />);
|
||||
expect(wrapper.snapshot).toMatchSnapshot();
|
||||
expect(wrapper.instance.findByType('ListBoxOption')).toHaveLength(2);
|
||||
});
|
||||
});
|
||||
@@ -1,49 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`TranslationModal renders correctly 1`] = `
|
||||
<StandardModal
|
||||
footerNode={
|
||||
<ActionRow>
|
||||
<Spacer />
|
||||
<Button
|
||||
onClick={[MockFunction close]}
|
||||
variant="tertiary"
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
onClick={[MockFunction onSubmit]}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</ActionRow>
|
||||
}
|
||||
isOpen={true}
|
||||
onClose={[MockFunction close]}
|
||||
title="Translate this course"
|
||||
>
|
||||
<ListBox
|
||||
className="listbox-container"
|
||||
>
|
||||
<ListBoxOption
|
||||
className="d-flex justify-content-between"
|
||||
key="en"
|
||||
onSelect={[Function]}
|
||||
selectedOptionIndex={0}
|
||||
>
|
||||
English
|
||||
<Icon
|
||||
src={[MockFunction icons.Check]}
|
||||
/>
|
||||
</ListBoxOption>
|
||||
<ListBoxOption
|
||||
className="d-flex justify-content-between"
|
||||
key="es"
|
||||
onSelect={[Function]}
|
||||
selectedOptionIndex={0}
|
||||
>
|
||||
Spanish
|
||||
</ListBoxOption>
|
||||
</ListBox>
|
||||
</StandardModal>
|
||||
`;
|
||||
@@ -1,50 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<TranslationSelection /> renders 1`] = `
|
||||
<Fragment>
|
||||
<ProductTour
|
||||
tours={
|
||||
Array [
|
||||
Object {
|
||||
"abitrarily": "defined",
|
||||
},
|
||||
]
|
||||
}
|
||||
/>
|
||||
<IconButton
|
||||
alt="change-language"
|
||||
className="mr-2 mb-2 float-right"
|
||||
iconAs="Icon"
|
||||
id="translation-selection-button"
|
||||
onClick={[MockFunction open]}
|
||||
src="Language"
|
||||
variant="primary"
|
||||
/>
|
||||
<TranslationModal
|
||||
availableLanguages={
|
||||
Array [
|
||||
Object {
|
||||
"code": "en",
|
||||
"label": "English",
|
||||
},
|
||||
Object {
|
||||
"code": "es",
|
||||
"label": "Spanish",
|
||||
},
|
||||
]
|
||||
}
|
||||
close={[MockFunction close]}
|
||||
courseId="course-v1:edX+DemoX+Demo_Course"
|
||||
id="plugin-test-id"
|
||||
isOpen={false}
|
||||
selectedLanguage="en"
|
||||
setSelectedLanguage={[MockFunction setSelectedLanguage]}
|
||||
/>
|
||||
<FeedbackWidget
|
||||
courseId="course-v1:edX+DemoX+Demo_Course"
|
||||
translationLanguage="en"
|
||||
unitId="unit-test-id"
|
||||
userId="123"
|
||||
/>
|
||||
</Fragment>
|
||||
`;
|
||||
@@ -1,100 +0,0 @@
|
||||
import React, { useContext, useEffect } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { AppContext } from '@edx/frontend-platform/react';
|
||||
import { IconButton, Icon, ProductTour } from '@openedx/paragon';
|
||||
import { Language } from '@openedx/paragon/icons';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { stringifyUrl } from 'query-string';
|
||||
|
||||
import { registerOverrideMethod } from '@src/generic/plugin-store';
|
||||
|
||||
import TranslationModal from './TranslationModal';
|
||||
import useTranslationTour from './useTranslationTour';
|
||||
import useSelectLanguage from './useSelectLanguage';
|
||||
import FeedbackWidget from '../feedback-widget';
|
||||
|
||||
const TranslationSelection = ({
|
||||
id, courseId, language, availableLanguages, unitId,
|
||||
}) => {
|
||||
const {
|
||||
authenticatedUser: { userId },
|
||||
} = useContext(AppContext);
|
||||
const dispatch = useDispatch();
|
||||
const {
|
||||
translationTour, isOpen, open, close,
|
||||
} = useTranslationTour();
|
||||
|
||||
const { selectedLanguage, setSelectedLanguage } = useSelectLanguage({
|
||||
courseId,
|
||||
language,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(
|
||||
registerOverrideMethod({
|
||||
pluginName: id,
|
||||
methodName: 'getIFrameUrl',
|
||||
method: (iframeUrl) => {
|
||||
const finalUrl = stringifyUrl({
|
||||
url: iframeUrl,
|
||||
query: {
|
||||
...(language
|
||||
&& selectedLanguage
|
||||
&& language !== selectedLanguage && {
|
||||
src_lang: language,
|
||||
dest_lang: selectedLanguage,
|
||||
}),
|
||||
},
|
||||
});
|
||||
return finalUrl;
|
||||
},
|
||||
}),
|
||||
);
|
||||
}, [language, selectedLanguage]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ProductTour tours={[translationTour]} />
|
||||
<IconButton
|
||||
src={Language}
|
||||
iconAs={Icon}
|
||||
alt="change-language"
|
||||
onClick={open}
|
||||
variant="primary"
|
||||
className="mr-2 mb-2 float-right"
|
||||
id="translation-selection-button"
|
||||
/>
|
||||
<TranslationModal
|
||||
isOpen={isOpen}
|
||||
close={close}
|
||||
courseId={courseId}
|
||||
selectedLanguage={selectedLanguage}
|
||||
setSelectedLanguage={setSelectedLanguage}
|
||||
availableLanguages={availableLanguages}
|
||||
id={id}
|
||||
/>
|
||||
<FeedbackWidget
|
||||
courseId={courseId}
|
||||
translationLanguage={selectedLanguage}
|
||||
unitId={unitId}
|
||||
userId={userId}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
TranslationSelection.propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
courseId: PropTypes.string.isRequired,
|
||||
unitId: PropTypes.string.isRequired,
|
||||
language: PropTypes.string.isRequired,
|
||||
availableLanguages: PropTypes.arrayOf(PropTypes.shape({
|
||||
code: PropTypes.string.isRequired,
|
||||
label: PropTypes.string.isRequired,
|
||||
})).isRequired,
|
||||
};
|
||||
|
||||
TranslationSelection.defaultProps = {};
|
||||
|
||||
export default TranslationSelection;
|
||||
@@ -1,63 +0,0 @@
|
||||
import { shallow } from '@edx/react-unit-test-utils';
|
||||
|
||||
import TranslationSelection from './index';
|
||||
|
||||
jest.mock('react', () => ({
|
||||
...jest.requireActual('react'),
|
||||
useContext: jest.fn().mockName('useContext').mockReturnValue({
|
||||
authenticatedUser: {
|
||||
userId: '123',
|
||||
},
|
||||
}),
|
||||
}));
|
||||
jest.mock('@openedx/paragon', () => ({
|
||||
IconButton: 'IconButton',
|
||||
Icon: 'Icon',
|
||||
ProductTour: 'ProductTour',
|
||||
}));
|
||||
jest.mock('@openedx/paragon/icons', () => ({
|
||||
Language: 'Language',
|
||||
}));
|
||||
jest.mock('./useTranslationTour', () => () => ({
|
||||
translationTour: {
|
||||
abitrarily: 'defined',
|
||||
},
|
||||
isOpen: false,
|
||||
open: jest.fn().mockName('open'),
|
||||
close: jest.fn().mockName('close'),
|
||||
}));
|
||||
jest.mock('react-redux', () => ({
|
||||
useDispatch: jest.fn().mockName('useDispatch'),
|
||||
}));
|
||||
jest.mock('@src/generic/plugin-store', () => ({
|
||||
registerOverrideMethod: jest.fn().mockName('registerOverrideMethod'),
|
||||
}));
|
||||
jest.mock('./TranslationModal', () => 'TranslationModal');
|
||||
jest.mock('./useSelectLanguage', () => () => ({
|
||||
selectedLanguage: 'en',
|
||||
setSelectedLanguage: jest.fn().mockName('setSelectedLanguage'),
|
||||
}));
|
||||
jest.mock('../feedback-widget', () => 'FeedbackWidget');
|
||||
|
||||
describe('<TranslationSelection />', () => {
|
||||
const props = {
|
||||
id: 'plugin-test-id',
|
||||
courseId: 'course-v1:edX+DemoX+Demo_Course',
|
||||
language: 'en',
|
||||
availableLanguages: [
|
||||
{
|
||||
code: 'en',
|
||||
label: 'English',
|
||||
},
|
||||
{
|
||||
code: 'es',
|
||||
label: 'Spanish',
|
||||
},
|
||||
],
|
||||
unitId: 'unit-test-id',
|
||||
};
|
||||
it('renders', () => {
|
||||
const wrapper = shallow(<TranslationSelection {...props} />);
|
||||
expect(wrapper.snapshot).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
@@ -1,41 +0,0 @@
|
||||
import { defineMessages } from '@edx/frontend-platform/i18n';
|
||||
|
||||
const messages = defineMessages({
|
||||
translationTourModalTitle: {
|
||||
id: 'translationSelection.translationTourModalTitle',
|
||||
defaultMessage: 'This is a standard modal dialog',
|
||||
description: 'Title for the translation modal.',
|
||||
},
|
||||
translationTourModalBody: {
|
||||
id: 'translationSelection.translationTourModalBody',
|
||||
defaultMessage: 'Now you can easily translate course content.',
|
||||
description: 'Body for the translation modal.',
|
||||
},
|
||||
tryItButtonText: {
|
||||
id: 'translationSelection.tryItButtonText',
|
||||
defaultMessage: 'Try it',
|
||||
description: 'Button text for the translation modal.',
|
||||
},
|
||||
dismissButtonText: {
|
||||
id: 'translationSelection.dismissButtonText',
|
||||
defaultMessage: 'Dismiss',
|
||||
description: 'Button text for the translation modal.',
|
||||
},
|
||||
languageSelectionModalTitle: {
|
||||
id: 'translationSelection.languageSelectionModalTitle',
|
||||
defaultMessage: 'Translate this course',
|
||||
description: 'Title for the translation modal.',
|
||||
},
|
||||
cancelButtonText: {
|
||||
id: 'translationSelection.cancelButtonText',
|
||||
defaultMessage: 'Cancel',
|
||||
description: 'Button text for the translation modal.',
|
||||
},
|
||||
submitButtonText: {
|
||||
id: 'translationSelection.submitButtonText',
|
||||
defaultMessage: 'Submit',
|
||||
description: 'Button text for the translation modal.',
|
||||
},
|
||||
});
|
||||
|
||||
export default messages;
|
||||
@@ -1,35 +0,0 @@
|
||||
import { useCallback } from 'react';
|
||||
import { StrictDict, useKeyedState } from '@edx/react-unit-test-utils';
|
||||
import {
|
||||
getLocalStorage,
|
||||
setLocalStorage,
|
||||
} from '@src/data/localStorage';
|
||||
|
||||
export const selectedLanguageKey = 'selectedLanguages';
|
||||
|
||||
export const stateKeys = StrictDict({
|
||||
selectedLanguage: 'selectedLanguage',
|
||||
});
|
||||
|
||||
const useSelectLanguage = ({ courseId, language }) => {
|
||||
const selectedLanguageItem = getLocalStorage(selectedLanguageKey) || {};
|
||||
const [selectedLanguage, updateSelectedLanguage] = useKeyedState(
|
||||
stateKeys.selectedLanguage,
|
||||
selectedLanguageItem[courseId] || language,
|
||||
);
|
||||
|
||||
const setSelectedLanguage = useCallback((newSelectedLanguage) => {
|
||||
setLocalStorage(selectedLanguageKey, {
|
||||
...selectedLanguageItem,
|
||||
[courseId]: newSelectedLanguage,
|
||||
});
|
||||
updateSelectedLanguage(newSelectedLanguage);
|
||||
});
|
||||
|
||||
return {
|
||||
selectedLanguage,
|
||||
setSelectedLanguage,
|
||||
};
|
||||
};
|
||||
|
||||
export default useSelectLanguage;
|
||||
@@ -1,63 +0,0 @@
|
||||
import { mockUseKeyedState } from '@edx/react-unit-test-utils';
|
||||
import {
|
||||
getLocalStorage,
|
||||
setLocalStorage,
|
||||
} from '@src/data/localStorage';
|
||||
|
||||
import useSelectLanguage, {
|
||||
stateKeys,
|
||||
selectedLanguageKey,
|
||||
} from './useSelectLanguage';
|
||||
|
||||
const state = mockUseKeyedState(stateKeys);
|
||||
|
||||
jest.mock('react', () => ({
|
||||
...jest.requireActual('react'),
|
||||
useCallback: jest.fn((cb, prereqs) => (...args) => [
|
||||
cb(...args),
|
||||
{ cb, prereqs },
|
||||
]),
|
||||
}));
|
||||
jest.mock('@src/data/localStorage', () => ({
|
||||
getLocalStorage: jest.fn(),
|
||||
setLocalStorage: jest.fn(),
|
||||
}));
|
||||
|
||||
describe('useSelectLanguage', () => {
|
||||
const props = {
|
||||
courseId: 'test-course-id',
|
||||
language: 'en',
|
||||
};
|
||||
const languages = [
|
||||
{ code: 'en', label: 'English' },
|
||||
{ code: 'es', label: 'Spanish' },
|
||||
];
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
state.mock();
|
||||
});
|
||||
afterEach(() => {
|
||||
state.resetVals();
|
||||
});
|
||||
|
||||
languages.forEach(({ code, label }) => {
|
||||
it(`initializes selectedLanguage to the selected language (${label})`, () => {
|
||||
getLocalStorage.mockReturnValueOnce({ [props.courseId]: code });
|
||||
const { selectedLanguage } = useSelectLanguage(props);
|
||||
|
||||
state.expectInitializedWith(stateKeys.selectedLanguage, code);
|
||||
expect(selectedLanguage).toBe(code);
|
||||
});
|
||||
});
|
||||
|
||||
test('setSelectedLanguage behavior', () => {
|
||||
const { setSelectedLanguage } = useSelectLanguage(props);
|
||||
|
||||
setSelectedLanguage('es');
|
||||
state.expectSetStateCalledWith(stateKeys.selectedLanguage, 'es');
|
||||
expect(setLocalStorage).toHaveBeenCalledWith(selectedLanguageKey, {
|
||||
[props.courseId]: 'es',
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,29 +0,0 @@
|
||||
import { useCallback } from 'react';
|
||||
import { StrictDict, useKeyedState } from '@edx/react-unit-test-utils';
|
||||
|
||||
export const stateKeys = StrictDict({
|
||||
selectedIndex: 'selectedIndex',
|
||||
});
|
||||
|
||||
const useTranslationModal = ({
|
||||
selectedLanguage, setSelectedLanguage, close, availableLanguages,
|
||||
}) => {
|
||||
const [selectedIndex, setSelectedIndex] = useKeyedState(
|
||||
stateKeys.selectedIndex,
|
||||
availableLanguages.findIndex((lang) => lang.code === selectedLanguage),
|
||||
);
|
||||
|
||||
const onSubmit = useCallback(() => {
|
||||
const newSelectedLanguage = availableLanguages[selectedIndex].code;
|
||||
setSelectedLanguage(newSelectedLanguage);
|
||||
close();
|
||||
}, [selectedIndex]);
|
||||
|
||||
return {
|
||||
selectedIndex,
|
||||
setSelectedIndex,
|
||||
onSubmit,
|
||||
};
|
||||
};
|
||||
|
||||
export default useTranslationModal;
|
||||
@@ -1,49 +0,0 @@
|
||||
import { mockUseKeyedState } from '@edx/react-unit-test-utils';
|
||||
|
||||
import useTranslationModal, { stateKeys } from './useTranslationModal';
|
||||
|
||||
const state = mockUseKeyedState(stateKeys);
|
||||
|
||||
jest.mock('react', () => ({
|
||||
...jest.requireActual('react'),
|
||||
useCallback: jest.fn((cb, prereqs) => (...args) => ([
|
||||
cb(...args), { cb, prereqs },
|
||||
])),
|
||||
}));
|
||||
|
||||
describe('useTranslationModal', () => {
|
||||
const props = {
|
||||
selectedLanguage: 'en',
|
||||
setSelectedLanguage: jest.fn(),
|
||||
close: jest.fn(),
|
||||
availableLanguages: [
|
||||
{ code: 'en', label: 'English' },
|
||||
{ code: 'es', label: 'Spanish' },
|
||||
],
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
state.mock();
|
||||
});
|
||||
afterEach(() => {
|
||||
state.resetVals();
|
||||
});
|
||||
|
||||
it('initializes selectedIndex to the index of the selected language', () => {
|
||||
const { selectedIndex } = useTranslationModal(props);
|
||||
|
||||
state.expectInitializedWith(stateKeys.selectedIndex, 0);
|
||||
expect(selectedIndex).toBe(0);
|
||||
});
|
||||
|
||||
it('onSubmit updates the selected language and closes the modal', () => {
|
||||
const { onSubmit } = useTranslationModal({
|
||||
...props,
|
||||
selectedLanguage: 'es',
|
||||
});
|
||||
onSubmit();
|
||||
expect(props.setSelectedLanguage).toHaveBeenCalledWith('es');
|
||||
expect(props.close).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -1,62 +0,0 @@
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { useIntl } from '@edx/frontend-platform/i18n';
|
||||
import { useToggle } from '@openedx/paragon';
|
||||
import { StrictDict, useKeyedState } from '@edx/react-unit-test-utils';
|
||||
|
||||
import messages from './messages';
|
||||
|
||||
const hasSeenTranslationTourKey = 'hasSeenTranslationTour';
|
||||
|
||||
export const stateKeys = StrictDict({
|
||||
showTranslationTour: 'showTranslationTour',
|
||||
});
|
||||
|
||||
const useTranslationTour = () => {
|
||||
const { formatMessage } = useIntl();
|
||||
|
||||
const [isTourEnabled, setIsTourEnabled] = useKeyedState(
|
||||
stateKeys.showTranslationTour,
|
||||
global.localStorage.getItem(hasSeenTranslationTourKey) !== 'true',
|
||||
);
|
||||
const [isOpen, open, close] = useToggle(false);
|
||||
|
||||
const endTour = useCallback(() => {
|
||||
global.localStorage.setItem(hasSeenTranslationTourKey, 'true');
|
||||
setIsTourEnabled(false);
|
||||
}, [isTourEnabled, setIsTourEnabled]);
|
||||
|
||||
const tryIt = useCallback(() => {
|
||||
endTour();
|
||||
open();
|
||||
}, [endTour, open]);
|
||||
|
||||
const translationTour = isTourEnabled
|
||||
? {
|
||||
tourId: 'translation',
|
||||
enabled: isTourEnabled,
|
||||
onDismiss: endTour,
|
||||
onEnd: tryIt,
|
||||
checkpoints: [
|
||||
{
|
||||
title: formatMessage(messages.translationTourModalTitle),
|
||||
body: formatMessage(messages.translationTourModalBody),
|
||||
placement: 'bottom',
|
||||
target: '#translation-selection-button',
|
||||
showDismissButton: true,
|
||||
endButtonText: formatMessage(messages.tryItButtonText),
|
||||
dismissButtonText: formatMessage(messages.dismissButtonText),
|
||||
},
|
||||
],
|
||||
}
|
||||
: {};
|
||||
|
||||
return {
|
||||
translationTour,
|
||||
isOpen,
|
||||
open,
|
||||
close,
|
||||
};
|
||||
};
|
||||
|
||||
export default useTranslationTour;
|
||||
@@ -1,95 +0,0 @@
|
||||
import { mockUseKeyedState } from '@edx/react-unit-test-utils';
|
||||
import { useToggle } from '@openedx/paragon';
|
||||
|
||||
import useTranslationTour, { stateKeys } from './useTranslationTour';
|
||||
|
||||
jest.mock('react', () => ({
|
||||
...jest.requireActual('react'),
|
||||
useCallback: jest.fn((cb, prereqs) => () => {
|
||||
cb();
|
||||
return { useCallback: { cb, prereqs } };
|
||||
}),
|
||||
}));
|
||||
jest.mock('@openedx/paragon', () => ({
|
||||
useToggle: jest.fn(),
|
||||
}));
|
||||
jest.mock('@edx/frontend-platform/i18n', () => {
|
||||
const i18n = jest.requireActual('@edx/frontend-platform/i18n');
|
||||
const { formatMessage } = jest.requireActual('@edx/react-unit-test-utils');
|
||||
// this provide consistent for the test on different platform/timezone
|
||||
const formatDate = jest.fn(date => new Date(date).toISOString()).mockName('useIntl.formatDate');
|
||||
return {
|
||||
...i18n,
|
||||
useIntl: jest.fn(() => ({
|
||||
formatMessage,
|
||||
formatDate,
|
||||
})),
|
||||
defineMessages: m => m,
|
||||
FormattedMessage: () => 'FormattedMessage',
|
||||
};
|
||||
});
|
||||
jest.mock('@src/data/localStorage', () => ({
|
||||
getLocalStorage: jest.fn(),
|
||||
setLocalStorage: jest.fn(),
|
||||
}));
|
||||
|
||||
const state = mockUseKeyedState(stateKeys);
|
||||
|
||||
describe('useTranslationSelection', () => {
|
||||
const mockLocalStroage = {
|
||||
getItem: jest.fn(),
|
||||
setItem: jest.fn(),
|
||||
};
|
||||
|
||||
const toggleOpen = jest.fn();
|
||||
const toggleClose = jest.fn();
|
||||
|
||||
useToggle.mockReturnValue([false, toggleOpen, toggleClose]);
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
state.mock();
|
||||
window.localStorage = mockLocalStroage;
|
||||
});
|
||||
afterEach(() => {
|
||||
state.resetVals();
|
||||
delete window.localStorage;
|
||||
});
|
||||
|
||||
it('do not have translation tour if user already seen it', () => {
|
||||
mockLocalStroage.getItem.mockReturnValueOnce('not seen');
|
||||
const { translationTour } = useTranslationTour();
|
||||
|
||||
expect(translationTour.enabled).toBe(true);
|
||||
});
|
||||
|
||||
it('show translation tour if user has not seen it', () => {
|
||||
mockLocalStroage.getItem.mockReturnValueOnce('true');
|
||||
const { translationTour } = useTranslationTour();
|
||||
|
||||
expect(translationTour).toMatchObject({});
|
||||
});
|
||||
test('open and close as pass from useToggle', () => {
|
||||
const { isOpen, open, close } = useTranslationTour();
|
||||
expect(isOpen).toBe(false);
|
||||
expect(toggleOpen).toBe(open);
|
||||
expect(toggleClose).toBe(close);
|
||||
});
|
||||
test('end tour on dismiss button click', () => {
|
||||
mockLocalStroage.getItem.mockReturnValueOnce('not seen');
|
||||
const { translationTour } = useTranslationTour();
|
||||
translationTour.onDismiss();
|
||||
expect(mockLocalStroage.setItem).toHaveBeenCalledWith(
|
||||
'hasSeenTranslationTour',
|
||||
'true',
|
||||
);
|
||||
state.expectSetStateCalledWith(stateKeys.showTranslationTour, false);
|
||||
});
|
||||
test('end tour and open modal on try it button click', () => {
|
||||
mockLocalStroage.getItem.mockReturnValueOnce('not seen');
|
||||
const { translationTour } = useTranslationTour();
|
||||
translationTour.onEnd();
|
||||
state.expectSetStateCalledWith(stateKeys.showTranslationTour, false);
|
||||
expect(toggleOpen).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -33,3 +33,19 @@ export const REDIRECT_MODES = {
|
||||
HOME_REDIRECT: 'home-redirect',
|
||||
SURVEY_REDIRECT: 'survey-redirect',
|
||||
};
|
||||
|
||||
export const VERIFIED_MODES = [
|
||||
'professional',
|
||||
'verified',
|
||||
'no-id-professional',
|
||||
'credit',
|
||||
'masters',
|
||||
'executive-education',
|
||||
'paid-executive-education',
|
||||
'paid-bootcamp',
|
||||
];
|
||||
|
||||
export const WIDGETS = {
|
||||
DISCUSSIONS: 'DISCUSSIONS',
|
||||
NOTIFICATIONS: 'NOTIFICATIONS',
|
||||
};
|
||||
|
||||
@@ -6,6 +6,7 @@ Factory.define('courseHomeMetadata')
|
||||
.option('host', 'http://localhost:18000')
|
||||
.attrs({
|
||||
title: 'Demonstration Course',
|
||||
is_new_discussion_sidebar_view_enabled: false,
|
||||
is_self_paced: false,
|
||||
is_enrolled: false,
|
||||
is_staff: false,
|
||||
|
||||
@@ -14,7 +14,11 @@ Object {
|
||||
},
|
||||
"courseware": Object {
|
||||
"courseId": null,
|
||||
"courseOutline": Object {},
|
||||
"courseOutlineShouldUpdate": false,
|
||||
"courseOutlineStatus": "loading",
|
||||
"courseStatus": "loading",
|
||||
"coursewareOutlineSidebarSettings": Object {},
|
||||
"sequenceId": null,
|
||||
"sequenceMightBeUnit": false,
|
||||
"sequenceStatus": "loading",
|
||||
@@ -38,6 +42,7 @@ Object {
|
||||
"id": "course-v1:edX+DemoX+Demo_Course",
|
||||
"isEnrolled": false,
|
||||
"isMasquerading": false,
|
||||
"isNewDiscussionSidebarViewEnabled": false,
|
||||
"isSelfPaced": false,
|
||||
"isStaff": false,
|
||||
"number": "DemoX",
|
||||
@@ -401,7 +406,11 @@ Object {
|
||||
},
|
||||
"courseware": Object {
|
||||
"courseId": null,
|
||||
"courseOutline": Object {},
|
||||
"courseOutlineShouldUpdate": false,
|
||||
"courseOutlineStatus": "loading",
|
||||
"courseStatus": "loading",
|
||||
"coursewareOutlineSidebarSettings": Object {},
|
||||
"sequenceId": null,
|
||||
"sequenceMightBeUnit": false,
|
||||
"sequenceStatus": "loading",
|
||||
@@ -425,6 +434,7 @@ Object {
|
||||
"id": "course-v1:edX+DemoX+Demo_Course",
|
||||
"isEnrolled": false,
|
||||
"isMasquerading": false,
|
||||
"isNewDiscussionSidebarViewEnabled": false,
|
||||
"isSelfPaced": false,
|
||||
"isStaff": false,
|
||||
"number": "DemoX",
|
||||
@@ -669,7 +679,11 @@ Object {
|
||||
},
|
||||
"courseware": Object {
|
||||
"courseId": null,
|
||||
"courseOutline": Object {},
|
||||
"courseOutlineShouldUpdate": false,
|
||||
"courseOutlineStatus": "loading",
|
||||
"courseStatus": "loading",
|
||||
"coursewareOutlineSidebarSettings": Object {},
|
||||
"sequenceId": null,
|
||||
"sequenceMightBeUnit": false,
|
||||
"sequenceStatus": "loading",
|
||||
@@ -693,6 +707,7 @@ Object {
|
||||
"id": "course-v1:edX+DemoX+Demo_Course",
|
||||
"isEnrolled": false,
|
||||
"isMasquerading": false,
|
||||
"isNewDiscussionSidebarViewEnabled": false,
|
||||
"isSelfPaced": false,
|
||||
"isStaff": false,
|
||||
"number": "DemoX",
|
||||
|
||||
@@ -30,7 +30,7 @@ const LmsHtmlFragment = ({
|
||||
const iframe = useRef(null);
|
||||
function resetIframeHeight() {
|
||||
if (iframe?.current?.contentWindow?.document?.body) {
|
||||
iframe.current.height = iframe.current.contentWindow.document.body.scrollHeight;
|
||||
iframe.current.height = iframe.current.contentWindow.document.body.parentNode.scrollHeight;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -282,6 +282,22 @@ describe('Outline Tab', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('ignores comments and misformatted HTML', async () => {
|
||||
setTabData({
|
||||
welcome_message_html: '<p class="additional-spaces-in-tag" >'
|
||||
+ '<!-- Even if the welcome_message_html length is above the limit because of comments, we hope it will not be shortened. -->'
|
||||
+ '<!-- Even if the welcome_message_html length is above the limit because of comments, we hope it will not be shortened. -->'
|
||||
+ 'Test welcome message that happens to be longer than one hundred words because of comments but displayed content is less.'
|
||||
+ 'It should not be shortened.'
|
||||
+ '<!-- Even if the welcome_message_html length is above the limit because of comments, we hope it will not be shortened. -->'
|
||||
+ '<!-- Even if the welcome_message_html length is above the limit because of comments, we hope it will not be shortened. -->'
|
||||
+ '</p>',
|
||||
});
|
||||
await fetchAndRender();
|
||||
const showMoreButton = screen.queryByRole('button', { name: 'Show More' });
|
||||
expect(showMoreButton).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('does not display if no update available', async () => {
|
||||
setTabData({ welcome_message_html: null });
|
||||
await fetchAndRender();
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import { Link } from 'react-router-dom';
|
||||
@@ -96,7 +95,7 @@ const SequenceLink = ({
|
||||
icon={fasCheckCircle}
|
||||
fixedWidth
|
||||
className="float-left text-success mt-1"
|
||||
aria-hidden="true"
|
||||
aria-hidden={complete}
|
||||
title={intl.formatMessage(messages.completedAssignment)}
|
||||
/>
|
||||
) : (
|
||||
@@ -104,7 +103,7 @@ const SequenceLink = ({
|
||||
icon={farCheckCircle}
|
||||
fixedWidth
|
||||
className="float-left text-gray-400 mt-1"
|
||||
aria-hidden="true"
|
||||
aria-hidden={complete}
|
||||
title={intl.formatMessage(messages.incompleteAssignment)}
|
||||
/>
|
||||
)}
|
||||
@@ -118,14 +117,14 @@ const SequenceLink = ({
|
||||
</div>
|
||||
</div>
|
||||
{hideFromTOC && (
|
||||
<div className="row w-100 my-2 mx-4 pl-3">
|
||||
<span className="small d-flex">
|
||||
<Icon className="mr-2" src={Block} data-testid="hide-from-toc-sequence-link-icon" />
|
||||
<span data-testid="hide-from-toc-sequence-link-text">
|
||||
{intl.formatMessage(messages.hiddenSequenceLink)}
|
||||
<div className="row w-100 my-2 mx-4 pl-3">
|
||||
<span className="small d-flex">
|
||||
<Icon className="mr-2" src={Block} data-testid="hide-from-toc-sequence-link-icon" />
|
||||
<span data-testid="hide-from-toc-sequence-link-text">
|
||||
{intl.formatMessage(messages.hiddenSequenceLink)}
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="row w-100 m-0 ml-3 pl-3">
|
||||
<small className="text-body pl-2">
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState } from 'react';
|
||||
import React, { useState, useMemo } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
|
||||
@@ -18,8 +18,22 @@ const WelcomeMessage = ({ courseId, intl }) => {
|
||||
|
||||
const [display, setDisplay] = useState(true);
|
||||
|
||||
const shortWelcomeMessageHtml = truncate(welcomeMessageHtml, 100, { byWords: true, keepWhitespaces: true });
|
||||
const messageCanBeShortened = shortWelcomeMessageHtml.length < welcomeMessageHtml.length;
|
||||
// welcomeMessageHtml can contain comments or malformatted HTML which can impact the length that determines
|
||||
// messageCanBeShortened. We clean it by calling truncate with a length of welcomeMessageHtml.length which
|
||||
// will not result in a truncation but a formatting into 'truncate-html' canonical format.
|
||||
const cleanedWelcomeMessageHtml = useMemo(
|
||||
() => truncate(welcomeMessageHtml, welcomeMessageHtml.length, { keepWhitespaces: true }),
|
||||
[welcomeMessageHtml],
|
||||
);
|
||||
const shortWelcomeMessageHtml = useMemo(
|
||||
() => truncate(cleanedWelcomeMessageHtml, 100, { byWords: true, keepWhitespaces: true }),
|
||||
[cleanedWelcomeMessageHtml],
|
||||
);
|
||||
const messageCanBeShortened = useMemo(
|
||||
() => (shortWelcomeMessageHtml.length < cleanedWelcomeMessageHtml.length),
|
||||
[cleanedWelcomeMessageHtml, shortWelcomeMessageHtml],
|
||||
);
|
||||
|
||||
const [showShortMessage, setShowShortMessage] = useState(messageCanBeShortened);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
@@ -63,7 +77,7 @@ const WelcomeMessage = ({ courseId, intl }) => {
|
||||
className="inline-link"
|
||||
data-testid="long-welcome-message-iframe"
|
||||
key="full-html"
|
||||
html={welcomeMessageHtml}
|
||||
html={cleanedWelcomeMessageHtml}
|
||||
title={intl.formatMessage(messages.welcomeMessage)}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -1,24 +1,23 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Helmet } from 'react-helmet';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import { breakpoints, useWindowSize } from '@openedx/paragon';
|
||||
|
||||
import { AlertList } from '../../generic/user-messages';
|
||||
|
||||
import Sequence from './sequence';
|
||||
|
||||
import { CelebrationModal, shouldCelebrateOnSectionLoad, WeeklyGoalCelebrationModal } from './celebration';
|
||||
import { AlertList } from '@src/generic/user-messages';
|
||||
import { useModel } from '@src/generic/model-store';
|
||||
import { getCoursewareOutlineSidebarSettings } from '../data/selectors';
|
||||
import { Trigger as CourseOutlineTrigger } from './sidebar/sidebars/course-outline';
|
||||
import Chat from './chat/Chat';
|
||||
import ContentTools from './content-tools';
|
||||
import CourseBreadcrumbs from './CourseBreadcrumbs';
|
||||
import SidebarProvider from './sidebar/SidebarContextProvider';
|
||||
import SidebarTriggers from './sidebar/SidebarTriggers';
|
||||
import NewSidebarProvider from './new-sidebar/SidebarContextProvider';
|
||||
import NewSidebarTriggers from './new-sidebar/SidebarTriggers';
|
||||
|
||||
import { useModel } from '../../generic/model-store';
|
||||
import { CelebrationModal, shouldCelebrateOnSectionLoad, WeeklyGoalCelebrationModal } from './celebration';
|
||||
import CourseBreadcrumbs from './CourseBreadcrumbs';
|
||||
import ContentTools from './content-tools';
|
||||
import Sequence from './sequence';
|
||||
|
||||
const Course = ({
|
||||
courseId,
|
||||
@@ -33,11 +32,12 @@ const Course = ({
|
||||
const {
|
||||
celebrations,
|
||||
isStaff,
|
||||
isNewDiscussionSidebarViewEnabled,
|
||||
} = useModel('courseHomeMeta', courseId);
|
||||
const sequence = useModel('sequences', sequenceId);
|
||||
const section = useModel('sections', sequence ? sequence.sectionId : null);
|
||||
const enableNewSidebar = getConfig().ENABLE_NEW_SIDEBAR;
|
||||
const navigationDisabled = sequence?.navigationDisabled ?? false;
|
||||
const { enableNavigationSidebar } = useSelector(getCoursewareOutlineSidebarSettings);
|
||||
const navigationDisabled = enableNavigationSidebar || (sequence?.navigationDisabled ?? false);
|
||||
|
||||
const pageTitleBreadCrumbs = [
|
||||
sequence,
|
||||
@@ -54,7 +54,6 @@ const Course = ({
|
||||
const [weeklyGoalCelebrationOpen, setWeeklyGoalCelebrationOpen] = useState(
|
||||
celebrations && !celebrations.streakLengthToCelebrate && celebrations.weeklyGoal,
|
||||
);
|
||||
const shouldDisplayTriggers = windowWidth >= breakpoints.small.minWidth;
|
||||
const shouldDisplayChat = windowWidth >= breakpoints.medium.minWidth;
|
||||
const daysPerWeek = course?.courseGoals?.selectedGoal?.daysPerWeek;
|
||||
|
||||
@@ -69,14 +68,14 @@ const Course = ({
|
||||
));
|
||||
}, [sequenceId]);
|
||||
|
||||
const SidebarProviderComponent = enableNewSidebar === 'true' ? NewSidebarProvider : SidebarProvider;
|
||||
const SidebarProviderComponent = isNewDiscussionSidebarViewEnabled ? NewSidebarProvider : SidebarProvider;
|
||||
|
||||
return (
|
||||
<SidebarProviderComponent courseId={courseId} unitId={unitId}>
|
||||
<Helmet>
|
||||
<title>{`${pageTitleBreadCrumbs.join(' | ')} | ${getConfig().SITE_NAME}`}</title>
|
||||
</Helmet>
|
||||
<div className="position-relative d-flex align-items-center mb-4 mt-1">
|
||||
<div className="position-relative d-flex align-items-xl-center mb-4 mt-1 flex-column flex-xl-row">
|
||||
{navigationDisabled || (
|
||||
<>
|
||||
<CourseBreadcrumbs
|
||||
@@ -100,11 +99,10 @@ const Course = ({
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{shouldDisplayTriggers && (
|
||||
<>
|
||||
{enableNewSidebar === 'true' ? <NewSidebarTriggers /> : <SidebarTriggers /> }
|
||||
</>
|
||||
)}
|
||||
<div className="w-100 d-flex align-items-center">
|
||||
<CourseOutlineTrigger isMobileView />
|
||||
{isNewDiscussionSidebarViewEnabled ? <NewSidebarTriggers /> : <SidebarTriggers /> }
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<AlertList topic="sequence" />
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Factory } from 'rosie';
|
||||
import { breakpoints } from '@openedx/paragon';
|
||||
|
||||
import {
|
||||
act, fireEvent, getByRole, initializeTestStore, loadUnit, render, screen, waitFor,
|
||||
fireEvent, getByRole, initializeTestStore, loadUnit, render, screen, waitFor,
|
||||
} from '../../setupTest';
|
||||
import * as celebrationUtils from './celebration/utils';
|
||||
import { handleNextSectionCelebration } from './celebration';
|
||||
@@ -59,7 +59,7 @@ describe('Course', () => {
|
||||
|
||||
it('loads learning sequence', async () => {
|
||||
render(<Course {...mockData} />, { wrapWithRouter: true });
|
||||
expect(screen.getByRole('navigation', { name: 'breadcrumb' })).toBeInTheDocument();
|
||||
expect(screen.queryByRole('navigation', { name: 'breadcrumb' })).not.toBeInTheDocument();
|
||||
expect(await screen.findByText('Loading learning sequence...')).toBeInTheDocument();
|
||||
|
||||
expect(screen.queryByRole('alert')).not.toBeInTheDocument();
|
||||
@@ -142,27 +142,32 @@ describe('Course', () => {
|
||||
|
||||
const notificationTrigger = screen.getByRole('button', { name: /Show notification tray/i });
|
||||
expect(notificationTrigger).toBeInTheDocument();
|
||||
expect(notificationTrigger.parentNode).not.toHaveClass('mt-3', { exact: true });
|
||||
expect(notificationTrigger.parentNode).not.toHaveClass('sidebar-active', { exact: true });
|
||||
fireEvent.click(notificationTrigger);
|
||||
expect(notificationTrigger.parentNode).toHaveClass('mt-3');
|
||||
expect(notificationTrigger.parentNode).toHaveClass('sidebar-active');
|
||||
});
|
||||
|
||||
it('handles click to open/close discussions sidebar', async () => {
|
||||
await setupDiscussionSidebar();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('sidebar-DISCUSSIONS')).toBeInTheDocument();
|
||||
expect(screen.getByTestId('sidebar-DISCUSSIONS')).not.toHaveClass('d-none');
|
||||
});
|
||||
|
||||
const discussionsTrigger = await screen.getByRole('button', { name: /Show discussions tray/i });
|
||||
const discussionsSideBar = await waitFor(() => screen.findByTestId('sidebar-DISCUSSIONS'));
|
||||
expect(discussionsTrigger).toBeInTheDocument();
|
||||
fireEvent.click(discussionsTrigger);
|
||||
|
||||
expect(discussionsSideBar).not.toHaveClass('d-none');
|
||||
|
||||
await act(async () => {
|
||||
fireEvent.click(discussionsTrigger);
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByTestId('sidebar-DISCUSSIONS')).not.toBeInTheDocument();
|
||||
});
|
||||
await expect(discussionsSideBar).toHaveClass('d-none');
|
||||
|
||||
await act(async () => {
|
||||
fireEvent.click(discussionsTrigger);
|
||||
fireEvent.click(discussionsTrigger);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByTestId('sidebar-DISCUSSIONS')).toBeInTheDocument();
|
||||
});
|
||||
await expect(discussionsSideBar).not.toHaveClass('d-none');
|
||||
});
|
||||
|
||||
it('displays discussions sidebar when unit changes', async () => {
|
||||
@@ -192,8 +197,9 @@ describe('Course', () => {
|
||||
it('handles click to open/close notification tray', async () => {
|
||||
await setupDiscussionSidebar();
|
||||
const notificationShowButton = await screen.findByRole('button', { name: /Show notification tray/i });
|
||||
expect(screen.queryByRole('region', { name: /notification tray/i })).toHaveClass('d-none');
|
||||
expect(screen.queryByRole('region', { name: /notification tray/i })).not.toBeInTheDocument();
|
||||
fireEvent.click(notificationShowButton);
|
||||
expect(screen.queryByRole('region', { name: /notification tray/i })).toBeInTheDocument();
|
||||
expect(screen.queryByRole('region', { name: /notification tray/i })).not.toHaveClass('d-none');
|
||||
});
|
||||
|
||||
@@ -204,7 +210,9 @@ describe('Course', () => {
|
||||
{ type: 'vertical' },
|
||||
{ courseId: courseMetadata.id },
|
||||
));
|
||||
const testStore = await initializeTestStore({ courseMetadata, unitBlocks }, false);
|
||||
const testStore = await initializeTestStore({
|
||||
courseMetadata, unitBlocks, enableNavigationSidebar: { enable_navigation_sidebar: false },
|
||||
}, false);
|
||||
const { courseware, models } = testStore.getState();
|
||||
const { courseId, sequenceId } = courseware;
|
||||
const testData = {
|
||||
|
||||
@@ -154,7 +154,7 @@ const CourseBreadcrumbs = ({
|
||||
}, [courseStatus, sequenceStatus, allSequencesInSections]);
|
||||
|
||||
return (
|
||||
<nav aria-label="breadcrumb" className="d-inline-block col-sm-10">
|
||||
<nav aria-label="breadcrumb" className="d-inline-block col-sm-10 mb-3">
|
||||
<ol className="list-unstyled d-flex flex-nowrap align-items-center m-0">
|
||||
<li className="list-unstyled col-auto m-0 p-0">
|
||||
<Link
|
||||
|
||||
@@ -5,6 +5,7 @@ import PropTypes from 'prop-types';
|
||||
import { Xpert } from '@edx/frontend-lib-learning-assistant';
|
||||
import { injectIntl } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import { VERIFIED_MODES } from '@src/constants';
|
||||
import { useModel } from '../../../generic/model-store';
|
||||
|
||||
const Chat = ({
|
||||
@@ -20,21 +21,10 @@ const Chat = ({
|
||||
} = useSelector(state => state.specialExams);
|
||||
const course = useModel('coursewareMeta', courseId);
|
||||
|
||||
const VERIFIED_MODES = [
|
||||
'professional',
|
||||
'verified',
|
||||
'no-id-professional',
|
||||
'credit',
|
||||
'masters',
|
||||
'executive-education',
|
||||
'paid-executive-education',
|
||||
'paid-bootcamp',
|
||||
];
|
||||
|
||||
const hasVerifiedEnrollment = (
|
||||
enrollmentMode !== null
|
||||
&& enrollmentMode !== undefined
|
||||
&& [...VERIFIED_MODES].some(mode => mode === enrollmentMode)
|
||||
&& VERIFIED_MODES.includes(enrollmentMode)
|
||||
);
|
||||
|
||||
const validDates = () => {
|
||||
|
||||
@@ -9,7 +9,7 @@ import { breakpoints, useWindowSize } from '@openedx/paragon';
|
||||
|
||||
import { getLocalStorage, setLocalStorage } from '../../../data/localStorage';
|
||||
import { useModel } from '../../../generic/model-store';
|
||||
import WIDGETS from './constants';
|
||||
import { WIDGETS } from '../../../constants';
|
||||
import SidebarContext from './SidebarContext';
|
||||
import { SIDEBARS } from './sidebars';
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import { Icon, IconButton } from '@openedx/paragon';
|
||||
import { ArrowBackIos, Close } from '@openedx/paragon/icons';
|
||||
|
||||
import { useEventListener } from '../../../../generic/hooks';
|
||||
import WIDGETS from '../constants';
|
||||
import { WIDGETS } from '../../../../constants';
|
||||
import messages from '../messages';
|
||||
import SidebarContext from '../SidebarContext';
|
||||
|
||||
@@ -41,7 +41,7 @@ const SidebarBase = ({
|
||||
|
||||
return (
|
||||
<section
|
||||
className={classNames('ml-0 ml-lg-4 h-auto align-top', {
|
||||
className={classNames('ml-0 ml-lg-4 h-auto align-top zindex-0', {
|
||||
'min-vh-100': !shouldDisplayFullScreen && allowFullHeight,
|
||||
'bg-white m-0 border-0 fixed-top vh-100 rounded-0': shouldDisplayFullScreen,
|
||||
'd-none': currentSidebar !== sidebarId,
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
const WIDGETS = {
|
||||
DISCUSSIONS: 'DISCUSSIONS',
|
||||
NOTIFICATIONS: 'NOTIFICATIONS',
|
||||
};
|
||||
|
||||
export default WIDGETS;
|
||||
@@ -14,19 +14,17 @@ const DiscussionsNotificationsSidebar = () => {
|
||||
const { hideNotificationbar } = useContext(SidebarContext);
|
||||
|
||||
return (
|
||||
<div className="sticky-top vh-100">
|
||||
<SidebarBase
|
||||
ariaLabel={intl.formatMessage(messages.discussionNotificationTray)}
|
||||
sidebarId={ID}
|
||||
className="d-flex flex-column flex-fill"
|
||||
showTitleBar={false}
|
||||
showBorder={false}
|
||||
>
|
||||
<NotificationTray />
|
||||
{!hideNotificationbar && <div className="my-1.5" />}
|
||||
<DiscussionsSidebar />
|
||||
</SidebarBase>
|
||||
</div>
|
||||
<SidebarBase
|
||||
ariaLabel={intl.formatMessage(messages.discussionNotificationTray)}
|
||||
sidebarId={ID}
|
||||
className="d-flex flex-column flex-fill"
|
||||
showTitleBar={false}
|
||||
showBorder={false}
|
||||
>
|
||||
<NotificationTray />
|
||||
{!hideNotificationbar && <div className="my-1.5" />}
|
||||
<DiscussionsSidebar />
|
||||
</SidebarBase>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import React, { useContext, useEffect, useMemo } from 'react';
|
||||
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
|
||||
import { useModel } from '../../../../../../generic/model-store';
|
||||
import UpgradeNotification from '../../../../../../generic/upgrade-notification/UpgradeNotification';
|
||||
import WIDGETS from '../../../constants';
|
||||
import { WIDGETS } from '../../../../../../constants';
|
||||
import SidebarContext from '../../../SidebarContext';
|
||||
|
||||
const NotificationsWidget = () => {
|
||||
|
||||
@@ -4,7 +4,7 @@ import React from 'react';
|
||||
import MockAdapter from 'axios-mock-adapter';
|
||||
import { Factory } from 'rosie';
|
||||
|
||||
import { mergeConfig, getConfig } from '@edx/frontend-platform';
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
|
||||
import { breakpoints } from '@openedx/paragon';
|
||||
|
||||
@@ -49,13 +49,11 @@ describe('NotificationsWidget', () => {
|
||||
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
|
||||
axiosMock.onGet(courseMetadataUrl).reply(200, defaultMetadata);
|
||||
axiosMock.onGet(courseHomeMetadataUrl).reply(200, courseHomeMetadata);
|
||||
mergeConfig({ ENABLE_NEW_SIDEBAR: 'true' }, 'Custom app config');
|
||||
});
|
||||
|
||||
it('successfully Open/Hide sidebar tray.', async () => {
|
||||
it('successfully Open/Hide sidebar tray', async () => {
|
||||
const userVerifiedMode = Factory.build('verifiedMode');
|
||||
|
||||
await setupDiscussionSidebar(userVerifiedMode);
|
||||
await setupDiscussionSidebar({ verifiedMode: userVerifiedMode, isNewDiscussionSidebarViewEnabled: true });
|
||||
|
||||
const sidebarButton = await screen.getByRole('button', { name: /Show sidebar tray/i });
|
||||
|
||||
@@ -129,7 +127,11 @@ describe('NotificationsWidget', () => {
|
||||
])('successfully %s', async ({ enabledInContext, testId }) => {
|
||||
const userVerifiedMode = Factory.build('verifiedMode');
|
||||
|
||||
await setupDiscussionSidebar(userVerifiedMode, enabledInContext);
|
||||
await setupDiscussionSidebar({
|
||||
verifiedMode: userVerifiedMode,
|
||||
enabledInContext,
|
||||
isNewDiscussionSidebarViewEnabled: true,
|
||||
});
|
||||
|
||||
const sidebarButton = screen.getByRole('button', { name: /Show sidebar tray/i });
|
||||
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
/* eslint-disable no-use-before-define */
|
||||
import React, {
|
||||
useEffect, useState,
|
||||
} from 'react';
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import { useEffect, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import {
|
||||
sendTrackEvent,
|
||||
@@ -13,17 +9,20 @@ import {
|
||||
import { useIntl } from '@edx/frontend-platform/i18n';
|
||||
import { useSelector } from 'react-redux';
|
||||
import SequenceExamWrapper from '@edx/frontend-lib-special-exams';
|
||||
import { breakpoints, useWindowSize } from '@openedx/paragon';
|
||||
|
||||
import PageLoading from '../../../generic/PageLoading';
|
||||
import { useModel } from '../../../generic/model-store';
|
||||
import { useSequenceBannerTextAlert, useSequenceEntranceExamAlert } from '../../../alerts/sequence-alerts/hooks';
|
||||
import PageLoading from '@src/generic/PageLoading';
|
||||
import { useModel } from '@src/generic/model-store';
|
||||
import { useSequenceBannerTextAlert, useSequenceEntranceExamAlert } from '@src/alerts/sequence-alerts/hooks';
|
||||
import SequenceContainerSlot from '../../../plugin-slots/SequenceContainerSlot';
|
||||
|
||||
import { getCoursewareOutlineSidebarSettings } from '../../data/selectors';
|
||||
import CourseLicense from '../course-license';
|
||||
import Sidebar from '../sidebar/Sidebar';
|
||||
import NewSidebar from '../new-sidebar/Sidebar';
|
||||
import SidebarTriggers from '../sidebar/SidebarTriggers';
|
||||
import NewSidebarTriggers from '../new-sidebar/SidebarTriggers';
|
||||
import {
|
||||
Trigger as CourseOutlineTrigger,
|
||||
Sidebar as CourseOutlineTray,
|
||||
} from '../sidebar/sidebars/course-outline';
|
||||
import messages from './messages';
|
||||
import HiddenAfterDue from './hidden-after-due';
|
||||
import { SequenceNavigation, UnitNavigation } from './sequence-navigation';
|
||||
@@ -45,30 +44,30 @@ const Sequence = ({
|
||||
const {
|
||||
isStaff,
|
||||
originalUserIsStaff,
|
||||
isNewDiscussionSidebarViewEnabled,
|
||||
} = useModel('courseHomeMeta', courseId);
|
||||
const sequence = useModel('sequences', sequenceId);
|
||||
const unit = useModel('units', unitId);
|
||||
const sequenceStatus = useSelector(state => state.courseware.sequenceStatus);
|
||||
const sequenceMightBeUnit = useSelector(state => state.courseware.sequenceMightBeUnit);
|
||||
const shouldDisplayNotificationTriggerInSequence = useWindowSize().width < breakpoints.small.minWidth;
|
||||
const enableNewSidebar = getConfig().ENABLE_NEW_SIDEBAR;
|
||||
const { enableNavigationSidebar: isEnabledOutlineSidebar } = useSelector(getCoursewareOutlineSidebarSettings);
|
||||
|
||||
const handleNext = () => {
|
||||
const nextIndex = sequence.unitIds.indexOf(unitId) + 1;
|
||||
if (nextIndex < sequence.unitIds.length) {
|
||||
const newUnitId = sequence.unitIds[nextIndex];
|
||||
handleNavigate(newUnitId);
|
||||
} else {
|
||||
const newUnitId = sequence.unitIds[nextIndex];
|
||||
handleNavigate(newUnitId);
|
||||
|
||||
if (nextIndex >= sequence.unitIds.length) {
|
||||
nextSequenceHandler();
|
||||
}
|
||||
};
|
||||
|
||||
const handlePrevious = () => {
|
||||
const previousIndex = sequence.unitIds.indexOf(unitId) - 1;
|
||||
if (previousIndex >= 0) {
|
||||
const newUnitId = sequence.unitIds[previousIndex];
|
||||
handleNavigate(newUnitId);
|
||||
} else {
|
||||
const newUnitId = sequence.unitIds[previousIndex];
|
||||
handleNavigate(newUnitId);
|
||||
|
||||
if (previousIndex < 0) {
|
||||
previousSequenceHandler();
|
||||
}
|
||||
};
|
||||
@@ -147,34 +146,50 @@ const Sequence = ({
|
||||
|
||||
const gated = sequence && sequence.gatedContent !== undefined && sequence.gatedContent.gated;
|
||||
|
||||
const renderUnitNavigation = (isAtTop) => (
|
||||
<UnitNavigation
|
||||
sequenceId={sequenceId}
|
||||
unitId={unitId}
|
||||
isAtTop={isAtTop}
|
||||
onClickPrevious={() => {
|
||||
logEvent('edx.ui.lms.sequence.previous_selected', 'bottom');
|
||||
handlePrevious();
|
||||
}}
|
||||
onClickNext={() => {
|
||||
logEvent('edx.ui.lms.sequence.next_selected', 'bottom');
|
||||
handleNext();
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
const defaultContent = (
|
||||
<>
|
||||
<div className="sequence-container d-inline-flex flex-row w-100">
|
||||
<div className={classNames('sequence w-100', { 'position-relative': shouldDisplayNotificationTriggerInSequence })}>
|
||||
<div className="sequence-navigation-container">
|
||||
<SequenceNavigation
|
||||
sequenceId={sequenceId}
|
||||
unitId={unitId}
|
||||
className="mb-4"
|
||||
nextHandler={() => {
|
||||
logEvent('edx.ui.lms.sequence.next_selected', 'top');
|
||||
handleNext();
|
||||
}}
|
||||
onNavigate={(destinationUnitId) => {
|
||||
logEvent('edx.ui.lms.sequence.tab_selected', 'top', destinationUnitId);
|
||||
handleNavigate(destinationUnitId);
|
||||
}}
|
||||
previousHandler={() => {
|
||||
logEvent('edx.ui.lms.sequence.previous_selected', 'top');
|
||||
handlePrevious();
|
||||
}}
|
||||
/>
|
||||
{shouldDisplayNotificationTriggerInSequence && (
|
||||
enableNewSidebar === 'true' ? <NewSidebarTriggers /> : <SidebarTriggers />
|
||||
)}
|
||||
</div>
|
||||
<CourseOutlineTrigger />
|
||||
<CourseOutlineTray />
|
||||
<div className="sequence w-100">
|
||||
{!isEnabledOutlineSidebar && (
|
||||
<div className="sequence-navigation-container">
|
||||
<SequenceNavigation
|
||||
sequenceId={sequenceId}
|
||||
unitId={unitId}
|
||||
nextHandler={() => {
|
||||
logEvent('edx.ui.lms.sequence.next_selected', 'top');
|
||||
handleNext();
|
||||
}}
|
||||
onNavigate={(destinationUnitId) => {
|
||||
logEvent('edx.ui.lms.sequence.tab_selected', 'top', destinationUnitId);
|
||||
handleNavigate(destinationUnitId);
|
||||
}}
|
||||
previousHandler={() => {
|
||||
logEvent('edx.ui.lms.sequence.previous_selected', 'top');
|
||||
handlePrevious();
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="unit-container flex-grow-1">
|
||||
<div className="unit-container flex-grow-1 pt-4">
|
||||
<SequenceContent
|
||||
courseId={courseId}
|
||||
gated={gated}
|
||||
@@ -182,25 +197,12 @@ const Sequence = ({
|
||||
unitId={unitId}
|
||||
unitLoadedHandler={handleUnitLoaded}
|
||||
/>
|
||||
{unitHasLoaded && (
|
||||
<UnitNavigation
|
||||
sequenceId={sequenceId}
|
||||
unitId={unitId}
|
||||
onClickPrevious={() => {
|
||||
logEvent('edx.ui.lms.sequence.previous_selected', 'bottom');
|
||||
handlePrevious();
|
||||
}}
|
||||
onClickNext={() => {
|
||||
logEvent('edx.ui.lms.sequence.next_selected', 'bottom');
|
||||
handleNext();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{unitHasLoaded && renderUnitNavigation(false)}
|
||||
</div>
|
||||
</div>
|
||||
{enableNewSidebar === 'true' ? <NewSidebar /> : <Sidebar />}
|
||||
{isNewDiscussionSidebarViewEnabled ? <NewSidebar /> : <Sidebar />}
|
||||
</div>
|
||||
<div id="whole-course-translation-feedback-widget" />
|
||||
<SequenceContainerSlot courseId={courseId} unitId={unitId} />
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -214,6 +216,7 @@ const Sequence = ({
|
||||
originalUserIsStaff={originalUserIsStaff}
|
||||
canAccessProctoredExams={canAccessProctoredExams}
|
||||
>
|
||||
{isEnabledOutlineSidebar && renderUnitNavigation(true)}
|
||||
{defaultContent}
|
||||
</SequenceExamWrapper>
|
||||
<CourseLicense license={license || undefined} />
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Factory } from 'rosie';
|
||||
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
|
||||
@@ -18,12 +17,14 @@ jest.mock('@edx/frontend-lib-special-exams/dist/data/thunks.js', () => ({
|
||||
|
||||
describe('Sequence', () => {
|
||||
let mockData;
|
||||
let defaultContextValue;
|
||||
const courseMetadata = Factory.build('courseMetadata');
|
||||
const unitBlocks = Array.from({ length: 3 }).map(() => Factory.build(
|
||||
'block',
|
||||
{ type: 'vertical' },
|
||||
{ courseId: courseMetadata.id },
|
||||
));
|
||||
const enableNavigationSidebar = { enable_navigation_sidebar: false };
|
||||
|
||||
beforeAll(async () => {
|
||||
const store = await initializeTestStore({ courseMetadata, unitBlocks });
|
||||
@@ -38,12 +39,29 @@ describe('Sequence', () => {
|
||||
toggleNotificationTray: () => {},
|
||||
setNotificationStatus: () => {},
|
||||
};
|
||||
defaultContextValue = { courseId: mockData.courseId, currentSidebar: null, toggleSidebar: jest.fn() };
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
global.innerWidth = breakpoints.extraLarge.minWidth;
|
||||
});
|
||||
|
||||
const SidebarWrapper = ({ contextValue = defaultContextValue, overrideData = {} }) => (
|
||||
<SidebarContext.Provider value={contextValue}>
|
||||
<Sequence {...({ ...mockData, ...overrideData })} />
|
||||
</SidebarContext.Provider>
|
||||
);
|
||||
|
||||
SidebarWrapper.defaultProps = {
|
||||
contextValue: defaultContextValue,
|
||||
overrideData: {},
|
||||
};
|
||||
|
||||
SidebarWrapper.propTypes = {
|
||||
contextValue: PropTypes.shape({}),
|
||||
overrideData: PropTypes.shape({}),
|
||||
};
|
||||
|
||||
it('renders correctly without data', async () => {
|
||||
const testStore = await initializeTestStore({ excludeFetchCourse: true, excludeFetchSequence: true }, false);
|
||||
render(
|
||||
@@ -74,18 +92,22 @@ describe('Sequence', () => {
|
||||
{ courseId: courseMetadata.id, unitBlocks, sequenceBlock: sequenceBlocks[0] },
|
||||
)];
|
||||
const testStore = await initializeTestStore({
|
||||
courseMetadata, unitBlocks, sequenceBlocks, sequenceMetadata,
|
||||
courseMetadata,
|
||||
unitBlocks,
|
||||
sequenceBlocks,
|
||||
sequenceMetadata,
|
||||
enableNavigationSidebar: { enable_navigation_sidebar: true },
|
||||
}, false);
|
||||
const { container } = render(
|
||||
<Sequence {...mockData} {...{ sequenceId: sequenceBlocks[0].id }} />,
|
||||
<SidebarWrapper overrideData={{ sequenceId: sequenceBlocks[0].id }} />,
|
||||
{ store: testStore, wrapWithRouter: true },
|
||||
);
|
||||
|
||||
await waitFor(() => expect(screen.queryByText('Loading locked content messaging...')).toBeInTheDocument());
|
||||
// `Previous`, `Prerequisite` and `Close Tray` buttons.
|
||||
expect(screen.getAllByRole('button').length).toEqual(3);
|
||||
// `Active` and `Next` buttons.
|
||||
expect(screen.getAllByRole('link').length).toEqual(2);
|
||||
// `Next` button.
|
||||
expect(screen.getAllByRole('link').length).toEqual(1);
|
||||
|
||||
expect(screen.getByText('Content Locked')).toBeInTheDocument();
|
||||
const unitContainer = container.querySelector('.unit-container');
|
||||
@@ -107,7 +129,7 @@ describe('Sequence', () => {
|
||||
{ courseId: courseMetadata.id, unitBlocks, sequenceBlock: sequenceBlocks[0] },
|
||||
)];
|
||||
const testStore = await initializeTestStore({
|
||||
courseMetadata, unitBlocks, sequenceBlocks, sequenceMetadata,
|
||||
courseMetadata, unitBlocks, sequenceBlocks, sequenceMetadata, enableNavigationSidebar,
|
||||
}, false);
|
||||
render(
|
||||
<Sequence {...mockData} {...{ sequenceId: sequenceBlocks[0].id }} />,
|
||||
@@ -134,18 +156,20 @@ describe('Sequence', () => {
|
||||
});
|
||||
|
||||
it('handles loading unit', async () => {
|
||||
render(<Sequence {...mockData} />, { wrapWithRouter: true });
|
||||
render(<SidebarWrapper />, { wrapWithRouter: true });
|
||||
expect(await screen.findByText('Loading learning sequence...')).toBeInTheDocument();
|
||||
// `Previous`, `Bookmark` and `Close Tray` buttons
|
||||
// `Previous`, `Prerequisite` and `Close Tray` buttons.
|
||||
expect(screen.getAllByRole('button')).toHaveLength(3);
|
||||
// Renders `Next` button plus one button for each unit.
|
||||
expect(screen.getAllByRole('link')).toHaveLength(1 + unitBlocks.length);
|
||||
// Renders `Next` button.
|
||||
expect(screen.getAllByRole('link')).toHaveLength(1);
|
||||
|
||||
loadUnit();
|
||||
await waitFor(() => expect(screen.queryByText('Loading learning sequence...')).not.toBeInTheDocument());
|
||||
// At this point there will be 2 `Previous` and 2 `Next` buttons.
|
||||
expect(screen.getAllByRole('button', { name: /previous/i }).length).toEqual(2);
|
||||
expect(screen.getAllByRole('link', { name: /next/i }).length).toEqual(2);
|
||||
// Renders two `Next` buttons for top and bottom unit navigations.
|
||||
expect(screen.getAllByRole('link')).toHaveLength(2);
|
||||
});
|
||||
|
||||
describe('sequence and unit navigation buttons', () => {
|
||||
@@ -161,7 +185,9 @@ describe('Sequence', () => {
|
||||
)];
|
||||
|
||||
beforeAll(async () => {
|
||||
testStore = await initializeTestStore({ courseMetadata, unitBlocks, sequenceBlocks }, false);
|
||||
testStore = await initializeTestStore({
|
||||
courseMetadata, unitBlocks, sequenceBlocks, enableNavigationSidebar,
|
||||
}, false);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -174,13 +200,13 @@ describe('Sequence', () => {
|
||||
sequenceId: sequenceBlocks[1].id,
|
||||
previousSequenceHandler: jest.fn(),
|
||||
};
|
||||
render(<Sequence {...testData} />, { store: testStore, wrapWithRouter: true });
|
||||
render(<SidebarWrapper overrideData={testData} />, { store: testStore, wrapWithRouter: true });
|
||||
expect(await screen.findByText('Loading learning sequence...')).toBeInTheDocument();
|
||||
|
||||
const sequencePreviousButton = screen.getByRole('link', { name: /previous/i });
|
||||
fireEvent.click(sequencePreviousButton);
|
||||
expect(testData.previousSequenceHandler).toHaveBeenCalledTimes(1);
|
||||
expect(sendTrackEvent).toHaveBeenCalledTimes(2);
|
||||
expect(sendTrackEvent).toHaveBeenCalledTimes(1);
|
||||
expect(sendTrackEvent).toHaveBeenCalledWith('edx.ui.lms.sequence.previous_selected', {
|
||||
current_tab: 1,
|
||||
id: testData.unitId,
|
||||
@@ -194,8 +220,8 @@ describe('Sequence', () => {
|
||||
.filter(button => button !== sequencePreviousButton)[0];
|
||||
fireEvent.click(unitPreviousButton);
|
||||
expect(testData.previousSequenceHandler).toHaveBeenCalledTimes(2);
|
||||
expect(sendTrackEvent).toHaveBeenCalledTimes(3);
|
||||
expect(sendTrackEvent).toHaveBeenNthCalledWith(3, 'edx.ui.lms.sequence.previous_selected', {
|
||||
expect(sendTrackEvent).toHaveBeenCalledTimes(2);
|
||||
expect(sendTrackEvent).toHaveBeenNthCalledWith(2, 'edx.ui.lms.sequence.previous_selected', {
|
||||
current_tab: 1,
|
||||
id: testData.unitId,
|
||||
tab_count: unitBlocks.length,
|
||||
@@ -210,7 +236,7 @@ describe('Sequence', () => {
|
||||
sequenceId: sequenceBlocks[0].id,
|
||||
nextSequenceHandler: jest.fn(),
|
||||
};
|
||||
render(<Sequence {...testData} />, { store: testStore, wrapWithRouter: true });
|
||||
render(<SidebarWrapper overrideData={testData} />, { store: testStore, wrapWithRouter: true });
|
||||
expect(await screen.findByText('Loading learning sequence...')).toBeInTheDocument();
|
||||
|
||||
const sequenceNextButton = screen.getByRole('link', { name: /next/i });
|
||||
@@ -229,8 +255,8 @@ describe('Sequence', () => {
|
||||
.filter(button => button !== sequenceNextButton)[0];
|
||||
fireEvent.click(unitNextButton);
|
||||
expect(testData.nextSequenceHandler).toHaveBeenCalledTimes(2);
|
||||
expect(sendTrackEvent).toHaveBeenCalledTimes(3);
|
||||
expect(sendTrackEvent).toHaveBeenNthCalledWith(3, 'edx.ui.lms.sequence.next_selected', {
|
||||
expect(sendTrackEvent).toHaveBeenCalledTimes(2);
|
||||
expect(sendTrackEvent).toHaveBeenNthCalledWith(2, 'edx.ui.lms.sequence.next_selected', {
|
||||
current_tab: unitBlocks.length,
|
||||
id: testData.unitId,
|
||||
tab_count: unitBlocks.length,
|
||||
@@ -248,7 +274,7 @@ describe('Sequence', () => {
|
||||
previousSequenceHandler: jest.fn(),
|
||||
nextSequenceHandler: jest.fn(),
|
||||
};
|
||||
render(<Sequence {...testData} />, { store: testStore, wrapWithRouter: true });
|
||||
render(<SidebarWrapper overrideData={testData} />, { store: testStore, wrapWithRouter: true });
|
||||
await waitFor(() => expect(screen.queryByText('Loading learning sequence...')).toBeInTheDocument());
|
||||
|
||||
fireEvent.click(screen.getByRole('link', { name: /previous/i }));
|
||||
@@ -261,7 +287,7 @@ describe('Sequence', () => {
|
||||
// Therefore the next unit will still be `the initial one + 1`.
|
||||
expect(testData.unitNavigationHandler).toHaveBeenNthCalledWith(2, unitBlocks[unitNumber + 1].id);
|
||||
|
||||
expect(sendTrackEvent).toHaveBeenCalledTimes(3);
|
||||
expect(sendTrackEvent).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it('handles the `Previous` buttons for the first unit in the first sequence', async () => {
|
||||
@@ -272,7 +298,7 @@ describe('Sequence', () => {
|
||||
unitNavigationHandler: jest.fn(),
|
||||
previousSequenceHandler: jest.fn(),
|
||||
};
|
||||
render(<Sequence {...testData} />, { store: testStore, wrapWithRouter: true });
|
||||
render(<SidebarWrapper overrideData={testData} />, { store: testStore, wrapWithRouter: true });
|
||||
loadUnit();
|
||||
await waitFor(() => expect(screen.queryByText('Loading learning sequence...')).not.toBeInTheDocument());
|
||||
|
||||
@@ -280,7 +306,7 @@ describe('Sequence', () => {
|
||||
|
||||
expect(testData.previousSequenceHandler).not.toHaveBeenCalled();
|
||||
expect(testData.unitNavigationHandler).not.toHaveBeenCalled();
|
||||
expect(sendTrackEvent).toHaveBeenCalled();
|
||||
expect(sendTrackEvent).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('handles the `Next` buttons for the last unit in the last sequence', async () => {
|
||||
@@ -291,7 +317,7 @@ describe('Sequence', () => {
|
||||
unitNavigationHandler: jest.fn(),
|
||||
nextSequenceHandler: jest.fn(),
|
||||
};
|
||||
render(<Sequence {...testData} />, { store: testStore, wrapWithRouter: true });
|
||||
render(<SidebarWrapper overrideData={testData} />, { store: testStore, wrapWithRouter: true });
|
||||
loadUnit();
|
||||
await waitFor(() => expect(screen.queryByText('Loading learning sequence...')).not.toBeInTheDocument());
|
||||
|
||||
@@ -299,7 +325,7 @@ describe('Sequence', () => {
|
||||
|
||||
expect(testData.nextSequenceHandler).not.toHaveBeenCalled();
|
||||
expect(testData.unitNavigationHandler).not.toHaveBeenCalled();
|
||||
expect(sendTrackEvent).toHaveBeenCalled();
|
||||
expect(sendTrackEvent).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('handles the navigation buttons for empty sequence', async () => {
|
||||
@@ -322,7 +348,11 @@ describe('Sequence', () => {
|
||||
{ courseId: courseMetadata.id, unitBlocks: block.children.length ? unitBlocks : [], sequenceBlock: block },
|
||||
));
|
||||
const innerTestStore = await initializeTestStore({
|
||||
courseMetadata, unitBlocks, sequenceBlocks: testSequenceBlocks, sequenceMetadata: testSequenceMetadata,
|
||||
courseMetadata,
|
||||
unitBlocks,
|
||||
sequenceBlocks: testSequenceBlocks,
|
||||
sequenceMetadata: testSequenceMetadata,
|
||||
enableNavigationSidebar,
|
||||
}, false);
|
||||
const testData = {
|
||||
...mockData,
|
||||
@@ -333,51 +363,37 @@ describe('Sequence', () => {
|
||||
nextSequenceHandler: jest.fn(),
|
||||
};
|
||||
|
||||
render(<Sequence {...testData} />, { store: innerTestStore, wrapWithRouter: true });
|
||||
render(<SidebarWrapper overrideData={testData} />, { store: innerTestStore, wrapWithRouter: true });
|
||||
loadUnit();
|
||||
await waitFor(() => expect(screen.queryByText('Loading learning sequence...')).not.toBeInTheDocument());
|
||||
|
||||
screen.getAllByRole('link', { name: /previous/i }).forEach(button => fireEvent.click(button));
|
||||
expect(testData.previousSequenceHandler).toHaveBeenCalledTimes(2);
|
||||
expect(testData.unitNavigationHandler).not.toHaveBeenCalled();
|
||||
expect(testData.unitNavigationHandler).toHaveBeenCalledTimes(2);
|
||||
|
||||
screen.getAllByRole('link', { name: /next/i }).forEach(button => fireEvent.click(button));
|
||||
expect(testData.nextSequenceHandler).toHaveBeenCalledTimes(2);
|
||||
expect(testData.unitNavigationHandler).not.toHaveBeenCalled();
|
||||
expect(testData.unitNavigationHandler).toHaveBeenCalledTimes(4);
|
||||
|
||||
expect(sendTrackEvent).toHaveBeenNthCalledWith(1, 'edx.ui.course.upgrade.old_sidebar.notifications', {
|
||||
course_end: undefined,
|
||||
course_modes: undefined,
|
||||
course_start: undefined,
|
||||
courserun_key: undefined,
|
||||
enrollment_end: undefined,
|
||||
enrollment_mode: undefined,
|
||||
enrollment_start: undefined,
|
||||
is_upgrade_notification_visible: false,
|
||||
name: 'Old Sidebar Notification Tray',
|
||||
org_key: undefined,
|
||||
username: undefined,
|
||||
verification_status: undefined,
|
||||
expect(sendTrackEvent).toHaveBeenNthCalledWith(1, 'edx.ui.lms.sequence.previous_selected', {
|
||||
current_tab: 1,
|
||||
id: testData.unitId,
|
||||
tab_count: 0,
|
||||
widget_placement: 'top',
|
||||
});
|
||||
expect(sendTrackEvent).toHaveBeenNthCalledWith(2, 'edx.ui.lms.sequence.previous_selected', {
|
||||
current_tab: 1,
|
||||
id: testData.unitId,
|
||||
tab_count: 0,
|
||||
widget_placement: 'top',
|
||||
});
|
||||
expect(sendTrackEvent).toHaveBeenNthCalledWith(3, 'edx.ui.lms.sequence.previous_selected', {
|
||||
current_tab: 1,
|
||||
id: testData.unitId,
|
||||
tab_count: 0,
|
||||
widget_placement: 'bottom',
|
||||
});
|
||||
expect(sendTrackEvent).toHaveBeenNthCalledWith(4, 'edx.ui.lms.sequence.next_selected', {
|
||||
expect(sendTrackEvent).toHaveBeenNthCalledWith(3, 'edx.ui.lms.sequence.next_selected', {
|
||||
current_tab: 1,
|
||||
id: testData.unitId,
|
||||
tab_count: 0,
|
||||
widget_placement: 'top',
|
||||
});
|
||||
expect(sendTrackEvent).toHaveBeenNthCalledWith(5, 'edx.ui.lms.sequence.next_selected', {
|
||||
expect(sendTrackEvent).toHaveBeenNthCalledWith(4, 'edx.ui.lms.sequence.next_selected', {
|
||||
current_tab: 1,
|
||||
id: testData.unitId,
|
||||
tab_count: 0,
|
||||
@@ -395,7 +411,7 @@ describe('Sequence', () => {
|
||||
sequenceId: sequenceBlocks[0].id,
|
||||
unitNavigationHandler: jest.fn(),
|
||||
};
|
||||
render(<Sequence {...testData} />, { store: testStore, wrapWithRouter: true });
|
||||
render(<SidebarWrapper overrideData={testData} />, { store: testStore, wrapWithRouter: true });
|
||||
await waitFor(() => expect(screen.queryByText('Loading learning sequence...')).toBeInTheDocument());
|
||||
|
||||
fireEvent.click(screen.getByRole('link', { name: targetUnit.display_name }));
|
||||
@@ -410,16 +426,6 @@ describe('Sequence', () => {
|
||||
});
|
||||
});
|
||||
|
||||
const SidebarWrapper = ({ contextValue }) => (
|
||||
<SidebarContext.Provider value={contextValue}>
|
||||
<Sequence {...mockData} />
|
||||
</SidebarContext.Provider>
|
||||
);
|
||||
|
||||
SidebarWrapper.propTypes = {
|
||||
contextValue: PropTypes.shape({}).isRequired,
|
||||
};
|
||||
|
||||
describe('notification feature', () => {
|
||||
it('renders notification tray in sequence', async () => {
|
||||
render(<SidebarWrapper contextValue={{ courseId: mockData.courseId, currentSidebar: 'NOTIFICATIONS', toggleSidebar: () => null }} />, { wrapWithRouter: true });
|
||||
@@ -431,7 +437,7 @@ describe('Sequence', () => {
|
||||
render(<SidebarWrapper contextValue={{ courseId: mockData.courseId, currentSidebar: 'NOTIFICATIONS', toggleSidebar: toggleNotificationTray }} />, { wrapWithRouter: true });
|
||||
const notificationCloseIconButton = await screen.findByRole('button', { name: /Close notification tray/i });
|
||||
fireEvent.click(notificationCloseIconButton);
|
||||
expect(toggleNotificationTray).toHaveBeenCalledTimes(1);
|
||||
expect(toggleNotificationTray).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('does not render notification tray in sequence by default if in responsive view', async () => {
|
||||
|
||||
@@ -28,14 +28,9 @@ exports[`Unit component output snapshot: not bookmarked, do not show content 1`]
|
||||
>
|
||||
unit-title
|
||||
</h3>
|
||||
<PluginSlot
|
||||
id="unit_title_plugin"
|
||||
pluginProps={
|
||||
Object {
|
||||
"courseId": "test-course-id",
|
||||
"unitId": "test-props-id",
|
||||
}
|
||||
}
|
||||
<UnitTitleSlot
|
||||
courseId="test-course-id"
|
||||
unitId="test-props-id"
|
||||
/>
|
||||
</div>
|
||||
<h2
|
||||
|
||||
@@ -50,12 +50,6 @@ const useIFrameBehavior = ({
|
||||
if (type === messageTypes.resize) {
|
||||
setIframeHeight(payload.height);
|
||||
|
||||
// We observe exit from the video xblock fullscreen mode
|
||||
// and scroll to the previously saved scroll position
|
||||
if (windowTopOffset !== null) {
|
||||
window.scrollTo(0, Number(windowTopOffset));
|
||||
}
|
||||
|
||||
if (!hasLoaded && iframeHeight === 0 && payload.height > 0) {
|
||||
setHasLoaded(true);
|
||||
if (onLoaded) {
|
||||
@@ -63,6 +57,12 @@ const useIFrameBehavior = ({
|
||||
}
|
||||
}
|
||||
} else if (type === messageTypes.videoFullScreen) {
|
||||
// We observe exit from the video xblock fullscreen mode
|
||||
// and scroll to the previously saved scroll position
|
||||
if (!payload.open && windowTopOffset !== null) {
|
||||
window.scrollTo(0, Number(windowTopOffset));
|
||||
}
|
||||
|
||||
// We listen for this message from LMS to know when we need to
|
||||
// save or reset scroll position on toggle video xblock fullscreen mode
|
||||
setWindowTopOffset(payload.open ? window.scrollY : null);
|
||||
|
||||
@@ -154,6 +154,9 @@ describe('useIFrameBehavior hook', () => {
|
||||
const resizeMessage = (height = 23) => ({
|
||||
data: { type: messageTypes.resize, payload: { height } },
|
||||
});
|
||||
const videoFullScreenMessage = (open = false) => ({
|
||||
data: { type: messageTypes.videoFullScreen, payload: { open } },
|
||||
});
|
||||
const testSetIFrameHeight = (height = 23) => {
|
||||
const { cb } = useEventListener.mock.calls[0][1];
|
||||
cb(resizeMessage(height));
|
||||
@@ -209,7 +212,7 @@ describe('useIFrameBehavior hook', () => {
|
||||
state.mockVals({ ...defaultStateVals, windowTopOffset });
|
||||
hook = useIFrameBehavior(props);
|
||||
const { cb } = useEventListener.mock.calls[0][1];
|
||||
cb(resizeMessage());
|
||||
cb(videoFullScreenMessage());
|
||||
expect(window.scrollTo).toHaveBeenCalledWith(0, windowTopOffset);
|
||||
});
|
||||
it('does not scroll if towverticalp offset is not set', () => {
|
||||
|
||||
@@ -9,7 +9,7 @@ export const stateKeys = StrictDict({
|
||||
options: 'options',
|
||||
});
|
||||
|
||||
export const DEFAULT_HEIGHT = '100vh';
|
||||
export const DEFAULT_HEIGHT = '100%';
|
||||
|
||||
const useModalIFrameData = () => {
|
||||
const [isOpen, setIsOpen] = useKeyedState(stateKeys.isOpen, false);
|
||||
|
||||
@@ -7,7 +7,6 @@ import { useIntl } from '@edx/frontend-platform/i18n';
|
||||
import { useModel } from '@src/generic/model-store';
|
||||
import { usePluginsCallback } from '@src/generic/plugin-store';
|
||||
|
||||
import { PluginSlot } from '@openedx/frontend-plugin-framework';
|
||||
import BookmarkButton from '../../bookmark/BookmarkButton';
|
||||
import messages from '../messages';
|
||||
import ContentIFrame from './ContentIFrame';
|
||||
@@ -15,6 +14,7 @@ import UnitSuspense from './UnitSuspense';
|
||||
import { modelKeys, views } from './constants';
|
||||
import { useExamAccess, useShouldDisplayHonorCode } from './hooks';
|
||||
import { getIFrameUrl } from './urls';
|
||||
import UnitTitleSlot from '../../../../plugin-slots/UnitTitleSlot';
|
||||
|
||||
const Unit = ({
|
||||
courseId,
|
||||
@@ -43,13 +43,7 @@ const Unit = ({
|
||||
<div className="unit">
|
||||
<div className="mb-0">
|
||||
<h3 className="h3">{unit.title}</h3>
|
||||
<PluginSlot
|
||||
id="unit_title_plugin"
|
||||
pluginProps={{
|
||||
courseId,
|
||||
unitId: id,
|
||||
}}
|
||||
/>
|
||||
<UnitTitleSlot courseId={courseId} unitId={id} />
|
||||
</div>
|
||||
<h2 className="sr-only">{formatMessage(messages.headerPlaceholder)}</h2>
|
||||
<BookmarkButton
|
||||
|
||||
@@ -1,26 +1,44 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import UnitButton from './UnitButton';
|
||||
import SequenceNavigationDropdown from './SequenceNavigationDropdown';
|
||||
import useIndexOfLastVisibleChild from '../../../../generic/tabs/useIndexOfLastVisibleChild';
|
||||
import {
|
||||
useIsOnXLDesktop, useIsOnMediumDesktop, useIsOnLargeDesktop, useIsSidebarOpen,
|
||||
} from './hooks';
|
||||
|
||||
const SequenceNavigationTabs = ({
|
||||
unitIds, unitId, showCompletion, onNavigate,
|
||||
}) => {
|
||||
const isSidebarOpen = useIsSidebarOpen(unitId);
|
||||
const [
|
||||
indexOfLastVisibleChild,
|
||||
containerRef,
|
||||
invisibleStyle,
|
||||
] = useIndexOfLastVisibleChild();
|
||||
const shouldDisplayDropdown = indexOfLastVisibleChild === -1;
|
||||
] = useIndexOfLastVisibleChild(isSidebarOpen);
|
||||
const isOnXLDesktop = useIsOnXLDesktop();
|
||||
const isOnLargeDesktop = useIsOnLargeDesktop();
|
||||
const isOnMediumDesktop = useIsOnMediumDesktop();
|
||||
const shouldDisplayDropdown = indexOfLastVisibleChild === -1 || indexOfLastVisibleChild < unitIds.length - 1;
|
||||
|
||||
return (
|
||||
<div style={{ flexBasis: '100%', minWidth: 0 }}>
|
||||
<div className="sequence-navigation-tabs-container" ref={containerRef}>
|
||||
<div
|
||||
style={{ flexBasis: '100%', minWidth: 0 }}
|
||||
className={classNames({
|
||||
'navigation-tab-width-xl': isOnXLDesktop && isSidebarOpen,
|
||||
'navigation-tab-width-large': isOnLargeDesktop && isSidebarOpen,
|
||||
'navigation-tab-width-medium': isOnMediumDesktop && isSidebarOpen,
|
||||
})}
|
||||
>
|
||||
<div
|
||||
className="sequence-navigation-tabs-container"
|
||||
>
|
||||
<div
|
||||
className="sequence-navigation-tabs d-flex flex-grow-1"
|
||||
style={shouldDisplayDropdown ? invisibleStyle : null}
|
||||
ref={containerRef}
|
||||
>
|
||||
{unitIds.map(buttonUnitId => (
|
||||
<UnitButton
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { Link } from 'react-router-dom';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Button } from '@openedx/paragon';
|
||||
@@ -21,6 +21,7 @@ const UnitNavigation = ({
|
||||
unitId,
|
||||
onClickPrevious,
|
||||
onClickNext,
|
||||
isAtTop,
|
||||
}) => {
|
||||
const {
|
||||
isFirstUnit, isLastUnit, nextLink, previousLink,
|
||||
@@ -33,7 +34,7 @@ const UnitNavigation = ({
|
||||
return (
|
||||
<Button
|
||||
variant="outline-secondary"
|
||||
className="previous-button mr-2 d-flex align-items-center justify-content-center"
|
||||
className="previous-button mr-sm-2 d-flex align-items-center justify-content-center"
|
||||
disabled={disabled}
|
||||
onClick={onClickPrevious}
|
||||
as={disabled ? undefined : Link}
|
||||
@@ -68,7 +69,7 @@ const UnitNavigation = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="unit-navigation d-flex">
|
||||
<div className={classNames('unit-navigation d-flex', { 'top-unit-navigation mb-3 w-100': isAtTop })}>
|
||||
{renderPreviousButton()}
|
||||
{renderNextButton()}
|
||||
</div>
|
||||
@@ -81,10 +82,12 @@ UnitNavigation.propTypes = {
|
||||
unitId: PropTypes.string,
|
||||
onClickPrevious: PropTypes.func.isRequired,
|
||||
onClickNext: PropTypes.func.isRequired,
|
||||
isAtTop: PropTypes.bool,
|
||||
};
|
||||
|
||||
UnitNavigation.defaultProps = {
|
||||
unitId: null,
|
||||
isAtTop: false,
|
||||
};
|
||||
|
||||
export default injectIntl(UnitNavigation);
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
/* eslint-disable import/prefer-default-export */
|
||||
|
||||
import { useContext } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { breakpoints, useWindowSize } from '@openedx/paragon';
|
||||
|
||||
import { useModel } from '../../../../generic/model-store';
|
||||
import { sequenceIdsSelector } from '../../../data';
|
||||
import SidebarContext from '../../sidebar/SidebarContext';
|
||||
import NewSidebarContext from '../../new-sidebar/SidebarContext';
|
||||
import { WIDGETS } from '../../../../constants';
|
||||
|
||||
export function useSequenceNavigationMetadata(currentSequenceId, currentUnitId) {
|
||||
const sequenceIds = useSelector(sequenceIdsSelector);
|
||||
@@ -68,3 +72,28 @@ export function useSequenceNavigationMetadata(currentSequenceId, currentUnitId)
|
||||
navigationDisabledPrevSequence,
|
||||
};
|
||||
}
|
||||
|
||||
export function useIsOnMediumDesktop() {
|
||||
const windowSize = useWindowSize();
|
||||
return windowSize.width >= breakpoints.medium.minWidth && windowSize.width < breakpoints.extraLarge.minWidth;
|
||||
}
|
||||
|
||||
export function useIsOnLargeDesktop() {
|
||||
const windowSize = useWindowSize();
|
||||
return windowSize.width >= breakpoints.extraLarge.minWidth && windowSize.width < breakpoints.extraLarge.maxWidth;
|
||||
}
|
||||
|
||||
export function useIsOnXLDesktop() {
|
||||
const windowSize = useWindowSize();
|
||||
return windowSize.width >= breakpoints.extraLarge.maxWidth;
|
||||
}
|
||||
|
||||
export function useIsSidebarOpen(unitId) {
|
||||
const courseId = useSelector(state => state.courseware.courseId);
|
||||
const { isNewDiscussionSidebarViewEnabled } = useModel('courseHomeMeta', courseId);
|
||||
const { currentSidebar } = useContext(isNewDiscussionSidebarViewEnabled ? NewSidebarContext : SidebarContext);
|
||||
const topic = useModel('discussionTopics', unitId);
|
||||
|
||||
return (currentSidebar === WIDGETS.NOTIFICATIONS) || (currentSidebar === 'DISCUSSIONS_NOTIFICATIONS') || (
|
||||
currentSidebar === WIDGETS.DISCUSSIONS && !!(topic?.id || topic?.enabledInContext));
|
||||
}
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
import React from 'react';
|
||||
import { SIDEBAR_ORDER, SIDEBARS } from './sidebars';
|
||||
import { useContext } from 'react';
|
||||
|
||||
const Sidebar = () => (
|
||||
<>
|
||||
{
|
||||
SIDEBAR_ORDER.map((sideBarId) => {
|
||||
const SidebarToRender = SIDEBARS[sideBarId].Sidebar;
|
||||
return <SidebarToRender key={sideBarId} />;
|
||||
})
|
||||
}
|
||||
</>
|
||||
);
|
||||
import SidebarContext from './SidebarContext';
|
||||
import { SIDEBARS } from './sidebars';
|
||||
|
||||
const Sidebar = () => {
|
||||
const { currentSidebar } = useContext(SidebarContext);
|
||||
|
||||
if (!currentSidebar || !SIDEBARS[currentSidebar]) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const SidebarToRender = SIDEBARS[currentSidebar].Sidebar;
|
||||
|
||||
return (
|
||||
<SidebarToRender />
|
||||
);
|
||||
};
|
||||
|
||||
export default Sidebar;
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
import { breakpoints, useWindowSize } from '@openedx/paragon';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, {
|
||||
import { useSelector } from 'react-redux';
|
||||
import {
|
||||
useEffect, useState, useMemo, useCallback,
|
||||
} from 'react';
|
||||
|
||||
import { useModel } from '../../../generic/model-store';
|
||||
import { getLocalStorage, setLocalStorage } from '../../../data/localStorage';
|
||||
import { useModel } from '@src/generic/model-store';
|
||||
import { getLocalStorage, setLocalStorage } from '@src/data/localStorage';
|
||||
import { getCoursewareOutlineSidebarSettings } from '../../data/selectors';
|
||||
|
||||
import * as discussionsSidebar from './sidebars/discussions';
|
||||
import * as notificationsSidebar from './sidebars/notifications';
|
||||
import SidebarContext from './SidebarContext';
|
||||
import { SIDEBARS } from './sidebars';
|
||||
|
||||
@@ -16,18 +20,35 @@ const SidebarProvider = ({
|
||||
children,
|
||||
}) => {
|
||||
const { verifiedMode } = useModel('courseHomeMeta', courseId);
|
||||
const shouldDisplayFullScreen = useWindowSize().width < breakpoints.large.minWidth;
|
||||
const shouldDisplaySidebarOpen = useWindowSize().width > breakpoints.medium.minWidth;
|
||||
const topic = useModel('discussionTopics', unitId);
|
||||
const isUnitHasDiscussionTopics = topic?.id && topic?.enabledInContext;
|
||||
const shouldDisplayFullScreen = useWindowSize().width < breakpoints.extraLarge.minWidth;
|
||||
const shouldDisplaySidebarOpen = useWindowSize().width > breakpoints.extraLarge.minWidth;
|
||||
const query = new URLSearchParams(window.location.search);
|
||||
const initialSidebar = (shouldDisplaySidebarOpen || query.get('sidebar') === 'true') ? SIDEBARS.DISCUSSIONS.ID : null;
|
||||
const { alwaysOpenAuxiliarySidebar } = useSelector(getCoursewareOutlineSidebarSettings);
|
||||
const isInitiallySidebarOpen = shouldDisplaySidebarOpen || query.get('sidebar') === 'true';
|
||||
|
||||
let initialSidebar = null;
|
||||
if (isInitiallySidebarOpen && alwaysOpenAuxiliarySidebar) {
|
||||
initialSidebar = isUnitHasDiscussionTopics
|
||||
? SIDEBARS[discussionsSidebar.ID].ID
|
||||
: verifiedMode && SIDEBARS[notificationsSidebar.ID].ID;
|
||||
}
|
||||
const [currentSidebar, setCurrentSidebar] = useState(initialSidebar);
|
||||
const [notificationStatus, setNotificationStatus] = useState(getLocalStorage(`notificationStatus.${courseId}`));
|
||||
const [upgradeNotificationCurrentState, setUpgradeNotificationCurrentState] = useState(getLocalStorage(`upgradeNotificationCurrentState.${courseId}`));
|
||||
|
||||
useEffect(() => {
|
||||
// if the user hasn't purchased the course, show the notifications sidebar
|
||||
setCurrentSidebar(verifiedMode ? SIDEBARS.NOTIFICATIONS.ID : SIDEBARS.DISCUSSIONS.ID);
|
||||
}, [unitId]);
|
||||
if (initialSidebar && currentSidebar !== initialSidebar) {
|
||||
setCurrentSidebar(initialSidebar);
|
||||
}
|
||||
}, [unitId, topic]);
|
||||
|
||||
useEffect(() => {
|
||||
if (initialSidebar) {
|
||||
setCurrentSidebar(initialSidebar);
|
||||
}
|
||||
}, [shouldDisplaySidebarOpen]);
|
||||
|
||||
const onNotificationSeen = useCallback(() => {
|
||||
setNotificationStatus('inactive');
|
||||
@@ -40,6 +61,7 @@ const SidebarProvider = ({
|
||||
}, [currentSidebar]);
|
||||
|
||||
const contextValue = useMemo(() => ({
|
||||
initialSidebar,
|
||||
toggleSidebar,
|
||||
onNotificationSeen,
|
||||
setNotificationStatus,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useContext } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import React, { useContext } from 'react';
|
||||
import { breakpoints, useWindowSize } from '@openedx/paragon';
|
||||
import SidebarContext from './SidebarContext';
|
||||
import { SIDEBAR_ORDER, SIDEBARS } from './sidebars';
|
||||
@@ -19,8 +19,8 @@ const SidebarTriggers = () => {
|
||||
const isActive = sidebarId === currentSidebar;
|
||||
return (
|
||||
<div
|
||||
className={classNames({ 'mt-3': !isMobileView, 'border-primary-700': isActive })}
|
||||
style={{ borderBottom: isActive ? '2px solid' : null }}
|
||||
className={classNames({ 'ml-1': !isMobileView, 'border-primary-700 sidebar-active': isActive })}
|
||||
style={{ borderBottom: '2px solid', borderColor: isActive ? 'inherit' : 'transparent' }}
|
||||
key={sidebarId}
|
||||
>
|
||||
<Trigger onClick={() => toggleSidebar(sidebarId)} key={sidebarId} />
|
||||
|
||||
@@ -3,8 +3,8 @@ import { Icon, IconButton } from '@openedx/paragon';
|
||||
import { ArrowBackIos, Close } from '@openedx/paragon/icons';
|
||||
import classNames from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { useCallback, useContext } from 'react';
|
||||
import { useEventListener } from '../../../../generic/hooks';
|
||||
import { useCallback, useContext } from 'react';
|
||||
import { useEventListener } from '@src/generic/hooks';
|
||||
import messages from '../../messages';
|
||||
import SidebarContext from '../SidebarContext';
|
||||
|
||||
@@ -36,14 +36,15 @@ const SidebarBase = ({
|
||||
|
||||
return (
|
||||
<section
|
||||
className={classNames('ml-0 ml-lg-4 border border-light-400 rounded-sm h-auto align-top', {
|
||||
className={classNames('ml-0 border border-light-400 rounded-sm h-auto align-top zindex-0', {
|
||||
'bg-white m-0 border-0 fixed-top vh-100 rounded-0': shouldDisplayFullScreen,
|
||||
'min-vh-100': !shouldDisplayFullScreen,
|
||||
'align-self-start': !shouldDisplayFullScreen,
|
||||
'd-none': currentSidebar !== sidebarId,
|
||||
}, className)}
|
||||
data-testid={`sidebar-${sidebarId}`}
|
||||
style={{ width: shouldDisplayFullScreen ? '100%' : width }}
|
||||
style={{ minWidth: shouldDisplayFullScreen ? '100%' : width }}
|
||||
aria-label={ariaLabel}
|
||||
id="course-sidebar"
|
||||
>
|
||||
{shouldDisplayFullScreen ? (
|
||||
<div
|
||||
@@ -52,7 +53,6 @@ const SidebarBase = ({
|
||||
onKeyDown={() => toggleSidebar(null)}
|
||||
role="button"
|
||||
tabIndex="0"
|
||||
alt={intl.formatMessage(messages.responsiveCloseNotificationTray)}
|
||||
>
|
||||
<Icon src={ArrowBackIos} />
|
||||
<span className="font-weight-bold m-2 d-inline-block">
|
||||
@@ -62,12 +62,12 @@ const SidebarBase = ({
|
||||
) : null}
|
||||
{showTitleBar && (
|
||||
<>
|
||||
<div className="d-flex align-items-center">
|
||||
<span className="p-2.5 d-inline-block">{title}</span>
|
||||
<div className="d-flex align-items-center mb-2">
|
||||
<strong className="p-2.5 d-inline-block course-sidebar-title">{title}</strong>
|
||||
{shouldDisplayFullScreen
|
||||
? null
|
||||
: (
|
||||
<div className="d-inline-flex mr-2 mt-1.5 ml-auto">
|
||||
<div className="d-inline-flex mr-2 ml-auto">
|
||||
<IconButton
|
||||
src={Close}
|
||||
size="sm"
|
||||
@@ -79,7 +79,6 @@ const SidebarBase = ({
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="py-1 bg-gray-100 border-top border-bottom border-light-400" />
|
||||
</>
|
||||
)}
|
||||
{children}
|
||||
@@ -92,16 +91,15 @@ SidebarBase.propTypes = {
|
||||
title: PropTypes.string.isRequired,
|
||||
ariaLabel: PropTypes.string.isRequired,
|
||||
sidebarId: PropTypes.string.isRequired,
|
||||
className: PropTypes.string,
|
||||
className: PropTypes.string.isRequired,
|
||||
children: PropTypes.element.isRequired,
|
||||
showTitleBar: PropTypes.bool,
|
||||
width: PropTypes.string,
|
||||
};
|
||||
|
||||
SidebarBase.defaultProps = {
|
||||
width: '31rem',
|
||||
width: '410px',
|
||||
showTitleBar: true,
|
||||
className: '',
|
||||
};
|
||||
|
||||
export default injectIntl(SidebarBase);
|
||||
|
||||
6
src/courseware/course/sidebar/common/SidebarBase.scss
Normal file
6
src/courseware/course/sidebar/common/SidebarBase.scss
Normal file
@@ -0,0 +1,6 @@
|
||||
#course-sidebar {
|
||||
@media (max-width: -1 + map-get($grid-breakpoints, "lg")) {
|
||||
overflow-y: scroll;
|
||||
padding: 0 .625rem !important;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { Button, useToggle, IconButton } from '@openedx/paragon';
|
||||
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
|
||||
import {
|
||||
MenuOpen as MenuOpenIcon,
|
||||
ChevronLeft as ChevronLeftIcon,
|
||||
} from '@openedx/paragon/icons';
|
||||
|
||||
import { useModel } from '@src/generic/model-store';
|
||||
import { LOADING, LOADED } from '@src/course-home/data/slice';
|
||||
import PageLoading from '@src/generic/PageLoading';
|
||||
import {
|
||||
getSequenceId,
|
||||
getCourseOutline,
|
||||
getCourseOutlineStatus,
|
||||
getCourseOutlineShouldUpdate,
|
||||
} from '../../../../data/selectors';
|
||||
import { getCourseOutlineStructure } from '../../../../data/thunks';
|
||||
import SidebarSection from './components/SidebarSection';
|
||||
import SidebarSequence from './components/SidebarSequence';
|
||||
import { ID } from './constants';
|
||||
import { useCourseOutlineSidebar } from './hooks';
|
||||
import messages from './messages';
|
||||
|
||||
const CourseOutlineTray = ({ intl }) => {
|
||||
const [selectedSection, setSelectedSection] = useState(null);
|
||||
const [isDisplaySequenceLevel, setDisplaySequenceLevel, setDisplaySectionLevel] = useToggle(true);
|
||||
|
||||
const dispatch = useDispatch();
|
||||
const activeSequenceId = useSelector(getSequenceId);
|
||||
const { sections = {}, sequences = {} } = useSelector(getCourseOutline);
|
||||
const courseOutlineStatus = useSelector(getCourseOutlineStatus);
|
||||
const courseOutlineShouldUpdate = useSelector(getCourseOutlineShouldUpdate);
|
||||
|
||||
const {
|
||||
courseId,
|
||||
unitId,
|
||||
isEnabledSidebar,
|
||||
currentSidebar,
|
||||
handleToggleCollapse,
|
||||
isActiveEntranceExam,
|
||||
shouldDisplayFullScreen,
|
||||
} = useCourseOutlineSidebar();
|
||||
|
||||
const {
|
||||
sectionId: activeSectionId,
|
||||
} = useModel('sequences', activeSequenceId);
|
||||
|
||||
const sectionsIds = Object.keys(sections);
|
||||
const sequenceIds = sections[selectedSection || activeSectionId]?.sequenceIds || [];
|
||||
const backButtonTitle = sections[selectedSection || activeSectionId]?.title;
|
||||
|
||||
const handleBackToSectionLevel = () => {
|
||||
setDisplaySectionLevel();
|
||||
setSelectedSection(null);
|
||||
};
|
||||
|
||||
const handleSelectSection = (id) => {
|
||||
setDisplaySequenceLevel();
|
||||
setSelectedSection(id);
|
||||
};
|
||||
|
||||
const sidebarHeading = (
|
||||
<div className="outline-sidebar-heading-wrapper sticky d-flex justify-content-between align-self-start align-items-center bg-light-200 p-2.5 pl-4">
|
||||
{isDisplaySequenceLevel && backButtonTitle ? (
|
||||
<Button
|
||||
variant="link"
|
||||
iconBefore={ChevronLeftIcon}
|
||||
className="outline-sidebar-heading p-0 mb-0 text-left text-dark-500"
|
||||
onClick={handleBackToSectionLevel}
|
||||
>
|
||||
{backButtonTitle}
|
||||
</Button>
|
||||
) : (
|
||||
<span className="outline-sidebar-heading mb-0 h4 text-dark-500">
|
||||
{intl.formatMessage(messages.courseOutlineTitle)}
|
||||
</span>
|
||||
)}
|
||||
<IconButton
|
||||
alt={intl.formatMessage(messages.toggleCourseOutlineTrigger)}
|
||||
className="outline-sidebar-toggle-btn flex-shrink-0 text-dark bg-light-200"
|
||||
iconAs={MenuOpenIcon}
|
||||
onClick={handleToggleCollapse}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if ((isEnabledSidebar && courseOutlineStatus !== LOADED) || courseOutlineShouldUpdate) {
|
||||
dispatch(getCourseOutlineStructure(courseId));
|
||||
}
|
||||
}, [courseId, isEnabledSidebar, courseOutlineShouldUpdate]);
|
||||
|
||||
if (!isEnabledSidebar || isActiveEntranceExam || currentSidebar !== ID) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (courseOutlineStatus === LOADING) {
|
||||
return (
|
||||
<div className={classNames('outline-sidebar-wrapper', {
|
||||
'flex-shrink-0 mr-4 h-auto': !shouldDisplayFullScreen,
|
||||
'bg-white m-0 fixed-top w-100 vh-100': shouldDisplayFullScreen,
|
||||
})}
|
||||
>
|
||||
<section className="outline-sidebar w-100">
|
||||
{sidebarHeading}
|
||||
<PageLoading
|
||||
srMessage={intl.formatMessage(messages.loading)}
|
||||
/>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classNames('outline-sidebar-wrapper', {
|
||||
'flex-shrink-0 mr-4 h-auto': !shouldDisplayFullScreen,
|
||||
'bg-white m-0 fixed-top w-100 vh-100': shouldDisplayFullScreen,
|
||||
})}
|
||||
>
|
||||
<section className="outline-sidebar w-100">
|
||||
{sidebarHeading}
|
||||
<ol id="outline-sidebar-outline" className="list-unstyled">
|
||||
{isDisplaySequenceLevel
|
||||
? sequenceIds.map((sequenceId) => (
|
||||
<SidebarSequence
|
||||
key={sequenceId}
|
||||
courseId={courseId}
|
||||
sequence={sequences[sequenceId]}
|
||||
defaultOpen={sequenceId === activeSequenceId}
|
||||
activeUnitId={unitId}
|
||||
/>
|
||||
))
|
||||
: sectionsIds.map((sectionId) => (
|
||||
<SidebarSection
|
||||
key={sectionId}
|
||||
courseId={courseId}
|
||||
section={sections[sectionId]}
|
||||
handleSelectSection={handleSelectSection}
|
||||
/>
|
||||
))}
|
||||
</ol>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
CourseOutlineTray.propTypes = {
|
||||
intl: intlShape.isRequired,
|
||||
};
|
||||
|
||||
CourseOutlineTray.ID = ID;
|
||||
|
||||
export default injectIntl(CourseOutlineTray);
|
||||
@@ -0,0 +1,103 @@
|
||||
.outline-sidebar-wrapper {
|
||||
width: 32.125rem;
|
||||
max-width: 100%;
|
||||
overflow: auto;
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.outline-sidebar {
|
||||
@media (min-width: map-get($grid-breakpoints, "xl")) {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.outline-sidebar-heading-wrapper {
|
||||
border: 1px solid #d7d3d1;
|
||||
|
||||
&.sticky {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.outline-sidebar-heading {
|
||||
font-weight: $font-weight-bold;
|
||||
}
|
||||
}
|
||||
|
||||
.course-sidebar-section {
|
||||
background: $white;
|
||||
border: 1px solid #d7d3d1;
|
||||
|
||||
button {
|
||||
line-height: 1.75rem;
|
||||
|
||||
&.focus::before,
|
||||
&:focus::before {
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.outline-sidebar-toggle-btn {
|
||||
font-size: 1.5rem;
|
||||
|
||||
.collapsed & {
|
||||
transform: scale(-1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
#outline-sidebar-outline {
|
||||
margin-top: -1px;
|
||||
|
||||
@media (min-width: map-get($grid-breakpoints, "xl")) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
font-size: 1rem;
|
||||
line-height: 1.5rem;
|
||||
|
||||
.collapsible-trigger {
|
||||
border-radius: 0;
|
||||
padding: map-get($spacers, 3\.5) map-get($spacers, 4) map-get($spacers, 3\.5) map-get($spacers, 5);
|
||||
|
||||
@media (max-width: -1 + map-get($grid-breakpoints, "sm")) {
|
||||
padding-left: map-get($spacers, 4);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: $light-500;
|
||||
}
|
||||
|
||||
.collapsible-icon {
|
||||
margin-inline-start: initial;
|
||||
}
|
||||
}
|
||||
|
||||
&:last-child .pgn_collapsible {
|
||||
@extend .mb-0;
|
||||
}
|
||||
}
|
||||
|
||||
.collapsible-body {
|
||||
padding: 0;
|
||||
|
||||
ol li > a {
|
||||
padding: map-get($spacers, 3\.5) map-get($spacers, 4) map-get($spacers, 3\.5) map-get($spacers, 5\.5);
|
||||
|
||||
@media (max-width: -1 + map-get($grid-breakpoints, "sm")) {
|
||||
padding-left: map-get($spacers, 4\.5);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
background-color: $light-500;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { AppProvider } from '@edx/frontend-platform/react';
|
||||
import { IntlProvider } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import { initializeTestStore } from '@src/setupTest';
|
||||
import courseOutlineMessages from '@src/course-home/outline-tab/messages';
|
||||
import SidebarContext from '../../SidebarContext';
|
||||
import CourseOutlineTray from './CourseOutlineTray';
|
||||
import { ID as outlineSidebarId } from './constants';
|
||||
import messages from './messages';
|
||||
|
||||
describe('<CourseOutlineTray />', () => {
|
||||
let store;
|
||||
let section = {};
|
||||
let sequence = {};
|
||||
let unit;
|
||||
let unitId;
|
||||
let courseId;
|
||||
let mockData;
|
||||
|
||||
const initTestStore = async (options) => {
|
||||
store = await initializeTestStore(options);
|
||||
const state = store.getState();
|
||||
courseId = state.courseware.courseId;
|
||||
[unitId] = Object.keys(state.models.units);
|
||||
|
||||
if (Object.keys(state.courseware.courseOutline).length) {
|
||||
const [activeSequenceId] = Object.keys(state.courseware.courseOutline.sequences);
|
||||
sequence = state.courseware.courseOutline.sequences[activeSequenceId];
|
||||
const activeSectionId = Object.keys(state.courseware.courseOutline.sections)[0];
|
||||
section = state.courseware.courseOutline.sections[activeSectionId];
|
||||
[unitId] = sequence.unitIds;
|
||||
unit = state.courseware.courseOutline.units[unitId];
|
||||
}
|
||||
|
||||
mockData = {
|
||||
courseId,
|
||||
unitId,
|
||||
currentSidebar: outlineSidebarId,
|
||||
toggleSidebar: jest.fn(),
|
||||
};
|
||||
};
|
||||
|
||||
function renderWithProvider(testData = {}) {
|
||||
const { container } = render(
|
||||
<AppProvider store={store} wrapWithRouter={false}>
|
||||
<IntlProvider locale="en">
|
||||
<SidebarContext.Provider value={{ ...mockData, ...testData }}>
|
||||
<MemoryRouter>
|
||||
<CourseOutlineTray />
|
||||
</MemoryRouter>
|
||||
</SidebarContext.Provider>
|
||||
</IntlProvider>
|
||||
</AppProvider>,
|
||||
);
|
||||
return container;
|
||||
}
|
||||
|
||||
it('renders correctly when course outline is loading', async () => {
|
||||
await initTestStore({ excludeFetchOutlineSidebar: true });
|
||||
renderWithProvider();
|
||||
|
||||
expect(screen.getByText(messages.loading.defaultMessage)).toBeInTheDocument();
|
||||
expect(screen.getByText(messages.courseOutlineTitle.defaultMessage)).toBeInTheDocument();
|
||||
expect(screen.queryByRole('button', { name: 'Course Outline' })).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('doesn\'t render when outline sidebar is disabled', async () => {
|
||||
await initTestStore({ enableNavigationSidebar: { enable_navigation_sidebar: false } });
|
||||
renderWithProvider();
|
||||
|
||||
await expect(screen.queryByText(messages.loading.defaultMessage)).not.toBeInTheDocument();
|
||||
expect(screen.queryByRole('button', { name: section.title })).not.toBeInTheDocument();
|
||||
expect(screen.queryByRole('button', { name: messages.toggleCourseOutlineTrigger.defaultMessage })).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders correctly when course outline is loaded', async () => {
|
||||
await initTestStore();
|
||||
renderWithProvider();
|
||||
|
||||
await expect(screen.queryByText(messages.loading.defaultMessage)).not.toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: section.title })).toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: messages.toggleCourseOutlineTrigger.defaultMessage })).toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: `${sequence.title} , ${courseOutlineMessages.incompleteAssignment.defaultMessage}` })).toBeInTheDocument();
|
||||
expect(screen.getByText(unit.title)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('collapses sidebar correctly when toggle button is clicked', async () => {
|
||||
const mockToggleSidebar = jest.fn();
|
||||
await initTestStore();
|
||||
renderWithProvider({ toggleSidebar: mockToggleSidebar });
|
||||
|
||||
const collapseBtn = screen.getByRole('button', { name: messages.toggleCourseOutlineTrigger.defaultMessage });
|
||||
const sidebarBackBtn = screen.queryByRole('button', { name: section.title });
|
||||
expect(sidebarBackBtn).toBeInTheDocument();
|
||||
expect(collapseBtn).toBeInTheDocument();
|
||||
|
||||
userEvent.click(collapseBtn);
|
||||
expect(mockToggleSidebar).toHaveBeenCalledWith(null);
|
||||
});
|
||||
|
||||
it('navigates to section or sequence level correctly on click by back/section button', async () => {
|
||||
await initTestStore();
|
||||
renderWithProvider();
|
||||
|
||||
const sidebarBackBtn = screen.queryByRole('button', { name: section.title });
|
||||
expect(sidebarBackBtn).toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: `${sequence.title} , ${courseOutlineMessages.incompleteAssignment.defaultMessage}` })).toBeInTheDocument();
|
||||
|
||||
userEvent.click(sidebarBackBtn);
|
||||
expect(sidebarBackBtn).not.toBeInTheDocument();
|
||||
expect(screen.queryByText(messages.courseOutlineTitle.defaultMessage)).toBeInTheDocument();
|
||||
|
||||
userEvent.click(screen.getByRole('button', { name: `${section.title} , ${courseOutlineMessages.incompleteSection.defaultMessage}` }));
|
||||
expect(screen.queryByRole('button', { name: section.title })).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,52 @@
|
||||
import classNames from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
|
||||
import { IconButton } from '@openedx/paragon';
|
||||
import { MenuOpen as MenuOpenIcon } from '@openedx/paragon/icons';
|
||||
|
||||
import { useCourseOutlineSidebar } from './hooks';
|
||||
import { ID } from './constants';
|
||||
import messages from './messages';
|
||||
|
||||
const CourseOutlineTrigger = ({ intl, isMobileView }) => {
|
||||
const {
|
||||
currentSidebar,
|
||||
shouldDisplayFullScreen,
|
||||
handleToggleCollapse,
|
||||
isActiveEntranceExam,
|
||||
isEnabledSidebar,
|
||||
} = useCourseOutlineSidebar();
|
||||
|
||||
const isDisplayForDesktopView = !isMobileView && !shouldDisplayFullScreen && currentSidebar !== ID;
|
||||
const isDisplayForMobileView = isMobileView && shouldDisplayFullScreen;
|
||||
|
||||
if ((!isDisplayForDesktopView && !isDisplayForMobileView) || !isEnabledSidebar || isActiveEntranceExam) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classNames('outline-sidebar-heading-wrapper bg-light-200 collapsed align-self-start', {
|
||||
'flex-shrink-0 mr-4 p-2.5': isDisplayForDesktopView,
|
||||
'p-0': isDisplayForMobileView,
|
||||
})}
|
||||
>
|
||||
<IconButton
|
||||
alt={intl.formatMessage(messages.toggleCourseOutlineTrigger)}
|
||||
className="outline-sidebar-toggle-btn flex-shrink-0 text-dark bg-light-200 rounded-0"
|
||||
iconAs={MenuOpenIcon}
|
||||
onClick={handleToggleCollapse}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
CourseOutlineTrigger.defaultProps = {
|
||||
isMobileView: false,
|
||||
};
|
||||
|
||||
CourseOutlineTrigger.propTypes = {
|
||||
intl: intlShape.isRequired,
|
||||
isMobileView: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default injectIntl(CourseOutlineTrigger);
|
||||
@@ -0,0 +1,109 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { AppProvider } from '@edx/frontend-platform/react';
|
||||
import { IntlProvider } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import { initializeTestStore } from '@src/setupTest';
|
||||
import SidebarContext from '../../SidebarContext';
|
||||
import { ID as discussionSidebarId } from '../discussions/DiscussionsTrigger';
|
||||
import CourseOutlineTrigger from './CourseOutlineTrigger';
|
||||
import { ID as outlineSidebarId } from './constants';
|
||||
import messages from './messages';
|
||||
|
||||
describe('<CourseOutlineTrigger />', () => {
|
||||
let mockData;
|
||||
let courseId;
|
||||
let unitId;
|
||||
let store;
|
||||
|
||||
const initTestStore = async (options) => {
|
||||
store = await initializeTestStore(options);
|
||||
const state = store.getState();
|
||||
courseId = state.courseware.courseId;
|
||||
[unitId] = Object.keys(state.models.units);
|
||||
|
||||
mockData = {
|
||||
courseId,
|
||||
unitId,
|
||||
currentSidebar: discussionSidebarId,
|
||||
};
|
||||
};
|
||||
|
||||
function renderWithProvider(testData = {}, props = {}) {
|
||||
const { container } = render(
|
||||
<AppProvider store={store} wrapWithRouter={false}>
|
||||
<IntlProvider locale="en">
|
||||
<SidebarContext.Provider value={{ ...mockData, ...testData }}>
|
||||
<CourseOutlineTrigger {...props} />
|
||||
</SidebarContext.Provider>
|
||||
</IntlProvider>
|
||||
</AppProvider>,
|
||||
);
|
||||
return container;
|
||||
}
|
||||
|
||||
it('renders correctly for desktop when sidebar is enabled', async () => {
|
||||
const mockToggleSidebar = jest.fn();
|
||||
await initTestStore({ enableNavigationSidebar: { enable_navigation_sidebar: true } });
|
||||
renderWithProvider({ toggleSidebar: mockToggleSidebar }, { isMobileView: false });
|
||||
|
||||
const toggleButton = await screen.getByRole('button', {
|
||||
name: messages.toggleCourseOutlineTrigger.defaultMessage,
|
||||
});
|
||||
expect(toggleButton).toBeInTheDocument();
|
||||
|
||||
userEvent.click(toggleButton);
|
||||
|
||||
expect(mockToggleSidebar).toHaveBeenCalled();
|
||||
expect(mockToggleSidebar).toHaveBeenCalledWith(outlineSidebarId);
|
||||
});
|
||||
|
||||
it('renders correctly for mobile when sidebar is enabled', async () => {
|
||||
const mockToggleSidebar = jest.fn();
|
||||
await initTestStore({ enableNavigationSidebar: { enable_navigation_sidebar: true } });
|
||||
renderWithProvider({
|
||||
toggleSidebar: mockToggleSidebar,
|
||||
shouldDisplayFullScreen: true,
|
||||
}, { isMobileView: true });
|
||||
|
||||
const toggleButton = await screen.getByRole('button', {
|
||||
name: messages.toggleCourseOutlineTrigger.defaultMessage,
|
||||
});
|
||||
expect(toggleButton).toBeInTheDocument();
|
||||
|
||||
userEvent.click(toggleButton);
|
||||
|
||||
expect(mockToggleSidebar).toHaveBeenCalled();
|
||||
expect(mockToggleSidebar).toHaveBeenCalledWith(outlineSidebarId);
|
||||
});
|
||||
|
||||
it('changes current sidebar value on click', async () => {
|
||||
const mockToggleSidebar = jest.fn();
|
||||
await initTestStore({ enableNavigationSidebar: { enable_navigation_sidebar: true } });
|
||||
renderWithProvider({
|
||||
toggleSidebar: mockToggleSidebar,
|
||||
shouldDisplayFullScreen: true,
|
||||
currentSidebar: outlineSidebarId,
|
||||
}, { isMobileView: true });
|
||||
|
||||
const toggleButton = await screen.getByRole('button', {
|
||||
name: messages.toggleCourseOutlineTrigger.defaultMessage,
|
||||
});
|
||||
expect(toggleButton).toBeInTheDocument();
|
||||
|
||||
userEvent.click(toggleButton);
|
||||
|
||||
expect(mockToggleSidebar).toHaveBeenCalledTimes(1);
|
||||
expect(mockToggleSidebar).toHaveBeenCalledWith(null);
|
||||
});
|
||||
|
||||
it('does not render when isEnabled is false', async () => {
|
||||
await initTestStore({ enableNavigationSidebar: { enable_navigation_sidebar: false } });
|
||||
renderWithProvider({}, { isMobileView: false });
|
||||
|
||||
const toggleButton = await screen.queryByRole('button', {
|
||||
name: messages.toggleCourseOutlineTrigger.defaultMessage,
|
||||
});
|
||||
expect(toggleButton).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,30 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
CheckCircle as CheckCircleIcon,
|
||||
LmsCompletionSolid as LmsCompletionSolidIcon,
|
||||
} from '@openedx/paragon/icons';
|
||||
|
||||
import { DashedCircleIcon } from '../icons';
|
||||
|
||||
const CompletionIcon = ({ completionStat: { completed = 0, total = 0 } }) => {
|
||||
const percentage = total !== 0 ? Math.min((completed / total) * 100, 100) : 0;
|
||||
const remainder = 100 - percentage;
|
||||
|
||||
switch (true) {
|
||||
case !completed:
|
||||
return <LmsCompletionSolidIcon className="text-gray-300" data-testid="completion-solid-icon" />;
|
||||
case completed === total:
|
||||
return <CheckCircleIcon className="text-success" data-testid="check-circle-icon" />;
|
||||
default:
|
||||
return <DashedCircleIcon percentage={percentage} remainder={remainder} data-testid="dashed-circle-icon" />;
|
||||
}
|
||||
};
|
||||
|
||||
CompletionIcon.propTypes = {
|
||||
completionStat: PropTypes.shape({
|
||||
completed: PropTypes.number,
|
||||
total: PropTypes.number,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
export default CompletionIcon;
|
||||
@@ -0,0 +1,23 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
|
||||
import CompletionIcon from './CompletionIcon';
|
||||
|
||||
describe('CompletionIcon', () => {
|
||||
it('renders check circle icon when completion is equal to total', () => {
|
||||
const completionStat = { completed: 5, total: 5 };
|
||||
render(<CompletionIcon completionStat={completionStat} />);
|
||||
expect(screen.getByTestId('check-circle-icon')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders dashed circle icon when completion is between 0 and total', () => {
|
||||
const completionStat = { completed: 2, total: 5 };
|
||||
render(<CompletionIcon completionStat={completionStat} />);
|
||||
expect(screen.getByTestId('dashed-circle-icon')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders completion solid icon when completion is 0', () => {
|
||||
const completionStat = { completed: 0, total: 5 };
|
||||
render(<CompletionIcon completionStat={completionStat} />);
|
||||
expect(screen.getByTestId('completion-solid-icon')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,72 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
|
||||
import { Button, Icon } from '@openedx/paragon';
|
||||
import { ChevronRight as ChevronRightIcon } from '@openedx/paragon/icons';
|
||||
|
||||
import courseOutlineMessages from '@src/course-home/outline-tab/messages';
|
||||
import { getSequenceId } from '@src/courseware/data/selectors';
|
||||
import CompletionIcon from './CompletionIcon';
|
||||
|
||||
const SidebarSection = ({ intl, section, handleSelectSection }) => {
|
||||
const {
|
||||
id,
|
||||
complete,
|
||||
title,
|
||||
sequenceIds,
|
||||
completionStat,
|
||||
} = section;
|
||||
|
||||
const activeSequenceId = useSelector(getSequenceId);
|
||||
const isActiveSection = sequenceIds.includes(activeSequenceId);
|
||||
|
||||
const sectionTitle = (
|
||||
<>
|
||||
<div className="col-auto p-0">
|
||||
<CompletionIcon completionStat={completionStat} />
|
||||
</div>
|
||||
<div className="col-10 ml-3 p-0 flex-grow-1 text-dark-500 text-left text-break">
|
||||
{title}
|
||||
<span className="sr-only">
|
||||
, {intl.formatMessage(complete
|
||||
? courseOutlineMessages.completedSection
|
||||
: courseOutlineMessages.incompleteSection)}
|
||||
</span>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
return (
|
||||
<li className="mb-2 course-sidebar-section">
|
||||
<Button
|
||||
variant="tertiary"
|
||||
className={classNames(
|
||||
'd-flex align-items-center w-100 px-4 py-3.5 rounded-0 justify-content-start',
|
||||
{ 'bg-info-100': isActiveSection },
|
||||
)}
|
||||
onClick={() => handleSelectSection(id)}
|
||||
>
|
||||
{sectionTitle}
|
||||
<Icon src={ChevronRightIcon} />
|
||||
</Button>
|
||||
</li>
|
||||
);
|
||||
};
|
||||
|
||||
SidebarSection.propTypes = {
|
||||
intl: intlShape.isRequired,
|
||||
section: PropTypes.shape({
|
||||
complete: PropTypes.bool,
|
||||
id: PropTypes.string,
|
||||
title: PropTypes.string,
|
||||
sequenceIds: PropTypes.arrayOf(PropTypes.string),
|
||||
completionStat: PropTypes.shape({
|
||||
completed: PropTypes.number,
|
||||
total: PropTypes.number,
|
||||
}),
|
||||
}).isRequired,
|
||||
handleSelectSection: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default injectIntl(SidebarSection);
|
||||
@@ -0,0 +1,67 @@
|
||||
import { render } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { IntlProvider } from '@edx/frontend-platform/i18n';
|
||||
import { AppProvider } from '@edx/frontend-platform/react';
|
||||
|
||||
import { initializeTestStore } from '@src/setupTest';
|
||||
import courseOutlineMessages from '@src/course-home/outline-tab/messages';
|
||||
import SidebarSection from './SidebarSection';
|
||||
|
||||
describe('<SidebarSection />', () => {
|
||||
let mockHandleSelectSection;
|
||||
let store;
|
||||
let section;
|
||||
|
||||
const initTestStore = async (options) => {
|
||||
store = await initializeTestStore(options);
|
||||
const state = store.getState();
|
||||
const [activeSectionId] = Object.keys(state.courseware.courseOutline.sections);
|
||||
section = state.courseware.courseOutline.sections[activeSectionId];
|
||||
};
|
||||
|
||||
const RootWrapper = (props) => (
|
||||
<AppProvider store={store} wrapWithRouter={false}>
|
||||
<IntlProvider locale="en">
|
||||
<SidebarSection
|
||||
section={section}
|
||||
handleSelectSection={mockHandleSelectSection}
|
||||
{...props}
|
||||
/>,
|
||||
</IntlProvider>
|
||||
</AppProvider>
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
mockHandleSelectSection = jest.fn();
|
||||
});
|
||||
|
||||
it('renders correctly when section is incomplete', async () => {
|
||||
await initTestStore();
|
||||
const { getByText, container } = render(<RootWrapper />);
|
||||
|
||||
expect(getByText(section.title)).toBeInTheDocument();
|
||||
expect(getByText(`, ${courseOutlineMessages.incompleteSection.defaultMessage}`)).toBeInTheDocument();
|
||||
expect(container.querySelector('.text-success')).not.toBeInTheDocument();
|
||||
|
||||
const button = getByText(section.title);
|
||||
userEvent.click(button);
|
||||
expect(mockHandleSelectSection).toHaveBeenCalledTimes(1);
|
||||
expect(mockHandleSelectSection).toHaveBeenCalledWith(section.id);
|
||||
});
|
||||
|
||||
it('renders correctly when section is complete', async () => {
|
||||
await initTestStore();
|
||||
const { getByText, getByTestId } = render(
|
||||
<RootWrapper section={{ ...section, completionStat: { completed: 4, total: 4 }, complete: true }} />,
|
||||
);
|
||||
|
||||
expect(getByText(section.title)).toBeInTheDocument();
|
||||
expect(getByText(`, ${courseOutlineMessages.completedSection.defaultMessage}`)).toBeInTheDocument();
|
||||
expect(getByTestId('check-circle-icon')).toBeInTheDocument();
|
||||
|
||||
const button = getByText(section.title);
|
||||
userEvent.click(button);
|
||||
expect(mockHandleSelectSection).toHaveBeenCalledTimes(1);
|
||||
expect(mockHandleSelectSection).toHaveBeenCalledWith(section.id);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,101 @@
|
||||
import { useState } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import classNames from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
|
||||
import { Collapsible } from '@openedx/paragon';
|
||||
|
||||
import courseOutlineMessages from '@src/course-home/outline-tab/messages';
|
||||
import { getCourseOutline, getSequenceId } from '@src/courseware/data/selectors';
|
||||
import CompletionIcon from './CompletionIcon';
|
||||
import SidebarUnit from './SidebarUnit';
|
||||
import { UNIT_ICON_TYPES } from './UnitIcon';
|
||||
|
||||
const SidebarSequence = ({
|
||||
intl,
|
||||
courseId,
|
||||
defaultOpen,
|
||||
sequence,
|
||||
activeUnitId,
|
||||
}) => {
|
||||
const {
|
||||
id,
|
||||
complete,
|
||||
title,
|
||||
specialExamInfo,
|
||||
unitIds,
|
||||
type,
|
||||
completionStat,
|
||||
} = sequence;
|
||||
|
||||
const [open, setOpen] = useState(defaultOpen);
|
||||
const { units = {} } = useSelector(getCourseOutline);
|
||||
const activeSequenceId = useSelector(getSequenceId);
|
||||
const isActiveSequence = id === activeSequenceId;
|
||||
|
||||
const sectionTitle = (
|
||||
<>
|
||||
<div className="col-auto p-0" style={{ fontSize: '1.1rem' }}>
|
||||
<CompletionIcon completionStat={completionStat} />
|
||||
</div>
|
||||
<div className="col-9 d-flex flex-column flex-grow-1 ml-3 mr-auto p-0 text-left">
|
||||
<span className="align-middle text-dark-500">{title}</span>
|
||||
{specialExamInfo && <span className="align-middle small text-muted">{specialExamInfo}</span>}
|
||||
<span className="sr-only">
|
||||
, {intl.formatMessage(complete
|
||||
? courseOutlineMessages.completedAssignment
|
||||
: courseOutlineMessages.incompleteAssignment)}
|
||||
</span>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
return (
|
||||
<li>
|
||||
<Collapsible
|
||||
className={classNames('mb-2', { 'active-section': isActiveSequence, 'bg-info-100': isActiveSequence && !open })}
|
||||
styling="card-lg text-break"
|
||||
title={sectionTitle}
|
||||
open={open}
|
||||
onToggle={() => setOpen(!open)}
|
||||
>
|
||||
<ol className="list-unstyled">
|
||||
{unitIds.map((unitId, index) => (
|
||||
<SidebarUnit
|
||||
key={unitId}
|
||||
id={unitId}
|
||||
courseId={courseId}
|
||||
sequenceId={id}
|
||||
unit={units[unitId]}
|
||||
isActive={activeUnitId === unitId}
|
||||
activeUnitId={activeUnitId}
|
||||
isFirst={index === 0}
|
||||
isLocked={type === UNIT_ICON_TYPES.lock}
|
||||
/>
|
||||
))}
|
||||
</ol>
|
||||
</Collapsible>
|
||||
</li>
|
||||
);
|
||||
};
|
||||
|
||||
SidebarSequence.propTypes = {
|
||||
intl: intlShape.isRequired,
|
||||
courseId: PropTypes.string.isRequired,
|
||||
defaultOpen: PropTypes.bool.isRequired,
|
||||
sequence: PropTypes.shape({
|
||||
complete: PropTypes.bool,
|
||||
id: PropTypes.string,
|
||||
title: PropTypes.string,
|
||||
type: PropTypes.string,
|
||||
specialExamInfo: PropTypes.string,
|
||||
unitIds: PropTypes.arrayOf(PropTypes.string),
|
||||
completionStat: PropTypes.shape({
|
||||
completed: PropTypes.number,
|
||||
total: PropTypes.number,
|
||||
}),
|
||||
}).isRequired,
|
||||
activeUnitId: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default injectIntl(SidebarSequence);
|
||||
@@ -0,0 +1,84 @@
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { render, screen, waitFor } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { AppProvider } from '@edx/frontend-platform/react';
|
||||
import { IntlProvider } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import courseOutlineMessages from '@src/course-home/outline-tab/messages';
|
||||
import { initializeMockApp, initializeTestStore } from '@src/setupTest';
|
||||
import messages from '../messages';
|
||||
import SidebarSequence from './SidebarSequence';
|
||||
|
||||
initializeMockApp();
|
||||
|
||||
describe('<SidebarSequence />', () => {
|
||||
let courseId;
|
||||
let store;
|
||||
let sequence;
|
||||
let unit;
|
||||
const sequenceDescription = 'sequence test description';
|
||||
|
||||
const initTestStore = async (options) => {
|
||||
store = await initializeTestStore(options);
|
||||
const state = store.getState();
|
||||
courseId = state.courseware.courseId;
|
||||
let activeSequenceId = '';
|
||||
[activeSequenceId] = Object.keys(state.courseware.courseOutline.sequences);
|
||||
sequence = state.courseware.courseOutline.sequences[activeSequenceId];
|
||||
const unitId = sequence.unitIds[0];
|
||||
unit = state.courseware.courseOutline.units[unitId];
|
||||
};
|
||||
|
||||
function renderWithProvider(props = {}) {
|
||||
const { container } = render(
|
||||
<AppProvider store={store} wrapWithRouter={false}>
|
||||
<IntlProvider locale="en">
|
||||
<MemoryRouter>
|
||||
<SidebarSequence
|
||||
courseId={courseId}
|
||||
defaultOpen={false}
|
||||
sequence={sequence}
|
||||
activeUnitId={sequence.unitIds[0]}
|
||||
{...props}
|
||||
/>
|
||||
</MemoryRouter>
|
||||
</IntlProvider>
|
||||
</AppProvider>,
|
||||
);
|
||||
return container;
|
||||
}
|
||||
|
||||
it('renders correctly when sequence is collapsed and incomplete', async () => {
|
||||
await initTestStore();
|
||||
renderWithProvider();
|
||||
|
||||
expect(screen.getByText(sequence.title)).toBeInTheDocument();
|
||||
expect(screen.queryByText(sequenceDescription)).not.toBeInTheDocument();
|
||||
expect(screen.getByText(`, ${courseOutlineMessages.incompleteAssignment.defaultMessage}`)).toBeInTheDocument();
|
||||
expect(screen.queryByText(unit.title)).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders correctly when sequence is not collapsed and complete', async () => {
|
||||
await initTestStore();
|
||||
renderWithProvider({
|
||||
defaultOpen: true,
|
||||
sequence: {
|
||||
...sequence,
|
||||
specialExamInfo: sequenceDescription,
|
||||
complete: true,
|
||||
},
|
||||
});
|
||||
|
||||
expect(screen.getByText(sequence.title)).toBeInTheDocument();
|
||||
expect(screen.getByText(sequenceDescription)).toBeInTheDocument();
|
||||
expect(screen.getByText(`, ${courseOutlineMessages.completedAssignment.defaultMessage}`)).toBeInTheDocument();
|
||||
expect(screen.getByText(unit.title)).toBeInTheDocument();
|
||||
expect(screen.getByText(`, ${messages.incompleteUnit.defaultMessage}`)).toBeInTheDocument();
|
||||
|
||||
userEvent.click(screen.getByText(sequence.title));
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByText(unit.title)).not.toBeInTheDocument();
|
||||
expect(screen.queryByText(`, ${messages.incompleteUnit.defaultMessage}`)).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,101 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
|
||||
import { sendTrackEvent, sendTrackingLogEvent } from '@edx/frontend-platform/analytics';
|
||||
|
||||
import { checkBlockCompletion } from '@src/courseware/data';
|
||||
import { getCourseOutline } from '@src/courseware/data/selectors';
|
||||
import messages from '../messages';
|
||||
import UnitIcon, { UNIT_ICON_TYPES } from './UnitIcon';
|
||||
|
||||
const SidebarUnit = ({
|
||||
id,
|
||||
intl,
|
||||
courseId,
|
||||
sequenceId,
|
||||
isFirst,
|
||||
unit,
|
||||
isActive,
|
||||
isLocked,
|
||||
activeUnitId,
|
||||
}) => {
|
||||
const {
|
||||
complete,
|
||||
title,
|
||||
icon = UNIT_ICON_TYPES.other,
|
||||
} = unit;
|
||||
const dispatch = useDispatch();
|
||||
const { sequences = {} } = useSelector(getCourseOutline);
|
||||
|
||||
const logEvent = (eventName, widgetPlacement) => {
|
||||
const findSequenceByUnitId = (unitId) => Object.values(sequences).find(seq => seq.unitIds.includes(unitId));
|
||||
const activeSequence = findSequenceByUnitId(activeUnitId);
|
||||
const targetSequence = findSequenceByUnitId(id);
|
||||
const payload = {
|
||||
id: activeUnitId,
|
||||
current_tab: activeSequence.unitIds.indexOf(activeUnitId) + 1,
|
||||
tab_count: activeSequence.unitIds.length,
|
||||
target_id: id,
|
||||
target_tab: targetSequence.unitIds.indexOf(id) + 1,
|
||||
widget_placement: widgetPlacement,
|
||||
};
|
||||
|
||||
if (activeSequence.id !== targetSequence.id) {
|
||||
payload.target_tab_count = targetSequence.unitIds.length;
|
||||
}
|
||||
|
||||
sendTrackEvent(eventName, payload);
|
||||
sendTrackingLogEvent(eventName, payload);
|
||||
};
|
||||
|
||||
const handleClick = () => {
|
||||
logEvent('edx.ui.lms.sequence.tab_selected', 'left');
|
||||
dispatch(checkBlockCompletion(courseId, sequenceId, activeUnitId));
|
||||
};
|
||||
|
||||
const iconType = isLocked ? UNIT_ICON_TYPES.lock : icon;
|
||||
|
||||
return (
|
||||
<li className={classNames({ 'bg-info-100': isActive, 'border-top border-light': !isFirst })}>
|
||||
<Link
|
||||
to={`/course/${courseId}/${sequenceId}/${id}`}
|
||||
className="row w-100 m-0 d-flex align-items-center text-gray-700"
|
||||
onClick={handleClick}
|
||||
>
|
||||
<div className="col-auto p-0">
|
||||
<UnitIcon type={iconType} isCompleted={complete} />
|
||||
</div>
|
||||
<div className="col-10 p-0 ml-3 text-break">
|
||||
<span className="align-middle">
|
||||
{title}
|
||||
</span>
|
||||
<span className="sr-only">
|
||||
, {intl.formatMessage(complete ? messages.completedUnit : messages.incompleteUnit)}
|
||||
</span>
|
||||
</div>
|
||||
</Link>
|
||||
</li>
|
||||
);
|
||||
};
|
||||
|
||||
SidebarUnit.propTypes = {
|
||||
intl: intlShape.isRequired,
|
||||
id: PropTypes.string.isRequired,
|
||||
isFirst: PropTypes.bool.isRequired,
|
||||
unit: PropTypes.shape({
|
||||
complete: PropTypes.bool,
|
||||
icon: PropTypes.string,
|
||||
id: PropTypes.string,
|
||||
title: PropTypes.string,
|
||||
type: PropTypes.string,
|
||||
}).isRequired,
|
||||
isActive: PropTypes.bool.isRequired,
|
||||
isLocked: PropTypes.bool.isRequired,
|
||||
courseId: PropTypes.string.isRequired,
|
||||
sequenceId: PropTypes.string.isRequired,
|
||||
activeUnitId: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default injectIntl(SidebarUnit);
|
||||
@@ -0,0 +1,107 @@
|
||||
import { AppProvider } from '@edx/frontend-platform/react';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { IntlProvider } from '@edx/frontend-platform/i18n';
|
||||
import { sendTrackEvent, sendTrackingLogEvent } from '@edx/frontend-platform/analytics';
|
||||
|
||||
import { initializeMockApp, initializeTestStore } from '@src/setupTest';
|
||||
import SidebarUnit from './SidebarUnit';
|
||||
|
||||
jest.mock('@edx/frontend-platform/analytics', () => ({
|
||||
sendTrackEvent: jest.fn(),
|
||||
sendTrackingLogEvent: jest.fn(),
|
||||
}));
|
||||
|
||||
initializeMockApp();
|
||||
|
||||
describe('<SidebarUnit />', () => {
|
||||
let store = {};
|
||||
let unit;
|
||||
let sequenceId;
|
||||
|
||||
const initTestStore = async (options) => {
|
||||
store = await initializeTestStore(options);
|
||||
const state = store.getState();
|
||||
[sequenceId] = Object.keys(state.courseware.courseOutline.sequences);
|
||||
const sequence = state.courseware.courseOutline.sequences[sequenceId];
|
||||
unit = state.courseware.courseOutline.units[sequence.unitIds[0]];
|
||||
};
|
||||
|
||||
function renderWithProvider(props = {}) {
|
||||
const { container } = render(
|
||||
<AppProvider store={store} wrapWithRouter={false}>
|
||||
<IntlProvider locale="en">
|
||||
<MemoryRouter>
|
||||
<SidebarUnit
|
||||
isFirst
|
||||
id={unit.id}
|
||||
courseId="course123"
|
||||
sequenceId={sequenceId}
|
||||
unit={{ ...unit, icon: 'video', isLocked: false }}
|
||||
isActive={false}
|
||||
activeUnitId={unit.id}
|
||||
{...props}
|
||||
/>
|
||||
</MemoryRouter>
|
||||
</IntlProvider>
|
||||
</AppProvider>,
|
||||
);
|
||||
return container;
|
||||
}
|
||||
|
||||
it('renders correctly when unit is incomplete', async () => {
|
||||
await initTestStore();
|
||||
const container = renderWithProvider();
|
||||
|
||||
expect(screen.getByText(unit.title)).toBeInTheDocument();
|
||||
expect(container.querySelector('.text-success')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders correctly when unit is complete', async () => {
|
||||
await initTestStore();
|
||||
const container = renderWithProvider({ unit: { ...unit, complete: true } });
|
||||
|
||||
expect(screen.getByText(unit.title)).toBeInTheDocument();
|
||||
expect(container.querySelector('.text-success')).toBeInTheDocument();
|
||||
expect(container.querySelector('.border-top')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders correctly when unit is not first and icon is not set', async () => {
|
||||
await initTestStore();
|
||||
const container = renderWithProvider({
|
||||
isFirst: false,
|
||||
unit: { ...unit, icon: null },
|
||||
});
|
||||
|
||||
expect(screen.getByText(unit.title)).toBeInTheDocument();
|
||||
expect(container.querySelector('.border-top')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders correctly when unit is locked', async () => {
|
||||
await initTestStore();
|
||||
renderWithProvider({
|
||||
unit: { ...unit, isLocked: true },
|
||||
});
|
||||
|
||||
expect(screen.getByText(unit.title)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('sends log event correctly when unit is clicked', async () => {
|
||||
await initTestStore();
|
||||
renderWithProvider({ unit: { ...unit } });
|
||||
const logData = {
|
||||
id: unit.id,
|
||||
current_tab: 1,
|
||||
tab_count: 1,
|
||||
target_id: unit.id,
|
||||
target_tab: 1,
|
||||
widget_placement: 'left',
|
||||
};
|
||||
|
||||
userEvent.click(screen.getByText(unit.title));
|
||||
|
||||
expect(sendTrackEvent).toHaveBeenCalledWith('edx.ui.lms.sequence.tab_selected', logData);
|
||||
expect(sendTrackingLogEvent).toHaveBeenCalledWith('edx.ui.lms.sequence.tab_selected', logData);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,56 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import {
|
||||
Locked as LockedIcon,
|
||||
Article as ArticleIcon,
|
||||
LmsBook as LmsBookIcon,
|
||||
LmsBookComplete as LmsBookCompleteIcon,
|
||||
LmsEditSquare as LmsEditSquareIcon,
|
||||
LmsEditSquareComplete as LmsEditSquareCompleteIcon,
|
||||
LmsVideocam as LmsVideocamIcon,
|
||||
LmsVideocamComplete as LmsVideocamCompleteIcon,
|
||||
} from '@openedx/paragon/icons';
|
||||
|
||||
export const UNIT_ICON_TYPES = {
|
||||
video: 'video',
|
||||
problem: 'problem',
|
||||
vertical: 'vertical',
|
||||
lock: 'lock',
|
||||
other: 'other',
|
||||
};
|
||||
|
||||
const UnitIcon = ({ type, isCompleted, ...props }) => {
|
||||
const iconMap = {
|
||||
[UNIT_ICON_TYPES.video]: {
|
||||
default: LmsVideocamIcon,
|
||||
complete: LmsVideocamCompleteIcon,
|
||||
},
|
||||
[UNIT_ICON_TYPES.problem]: {
|
||||
default: LmsEditSquareIcon,
|
||||
complete: LmsEditSquareCompleteIcon,
|
||||
},
|
||||
[UNIT_ICON_TYPES.vertical]: ArticleIcon,
|
||||
[UNIT_ICON_TYPES.lock]: LockedIcon,
|
||||
[UNIT_ICON_TYPES.other]: {
|
||||
default: LmsBookIcon,
|
||||
complete: LmsBookCompleteIcon,
|
||||
},
|
||||
};
|
||||
|
||||
let Icon = iconMap[type || UNIT_ICON_TYPES.other];
|
||||
|
||||
if (typeof Icon === 'object') {
|
||||
Icon = iconMap[type || UNIT_ICON_TYPES.other]?.[isCompleted ? 'complete' : 'default'];
|
||||
}
|
||||
|
||||
return (
|
||||
<Icon {...props} className={classNames({ 'text-success': isCompleted, 'text-gray-300': !isCompleted })} />
|
||||
);
|
||||
};
|
||||
|
||||
UnitIcon.propTypes = {
|
||||
type: PropTypes.oneOf(Object.keys(UNIT_ICON_TYPES)).isRequired,
|
||||
isCompleted: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
export default UnitIcon;
|
||||
@@ -0,0 +1,21 @@
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import UnitIcon, { UNIT_ICON_TYPES } from './UnitIcon';
|
||||
|
||||
describe('<UnitIcon />', () => {
|
||||
Object.keys(UNIT_ICON_TYPES).forEach((type) => {
|
||||
it(`renders default ${type} icon correctly`, () => {
|
||||
const { container } = render(<UnitIcon type={type} isCompleted={false} />);
|
||||
const icon = container.querySelector('svg');
|
||||
expect(icon).toBeInTheDocument();
|
||||
expect(icon).not.toHaveClass('text-success');
|
||||
});
|
||||
|
||||
it(`renders default ${type} completed icon correctly`, () => {
|
||||
const { container } = render(<UnitIcon type={type} isCompleted />);
|
||||
const icon = container.querySelector('svg');
|
||||
expect(icon).toBeInTheDocument();
|
||||
expect(icon).toHaveClass('text-success');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,2 @@
|
||||
// eslint-disable-next-line import/prefer-default-export
|
||||
export const ID = 'COURSE_OUTLINE';
|
||||
@@ -0,0 +1,59 @@
|
||||
import { useContext, useEffect, useState } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import { useModel } from '@src/generic/model-store';
|
||||
import SidebarContext from '@src/courseware/course/sidebar/SidebarContext';
|
||||
import { getCoursewareOutlineSidebarSettings } from '@src/courseware/data/selectors';
|
||||
import { ID } from './constants';
|
||||
|
||||
// eslint-disable-next-line import/prefer-default-export
|
||||
export const useCourseOutlineSidebar = () => {
|
||||
const isCollapsedOutlineSidebar = window.sessionStorage.getItem('hideCourseOutlineSidebar');
|
||||
const { enableNavigationSidebar: isEnabledSidebar } = useSelector(getCoursewareOutlineSidebarSettings);
|
||||
const {
|
||||
unitId,
|
||||
courseId,
|
||||
initialSidebar,
|
||||
currentSidebar,
|
||||
toggleSidebar,
|
||||
shouldDisplayFullScreen,
|
||||
} = useContext(SidebarContext);
|
||||
|
||||
const isOpenSidebar = !initialSidebar && isEnabledSidebar && !isCollapsedOutlineSidebar;
|
||||
const [isOpen, setIsOpen] = useState(true);
|
||||
|
||||
const course = useModel('coursewareMeta', courseId);
|
||||
const {
|
||||
entranceExamEnabled,
|
||||
entranceExamPassed,
|
||||
} = course.entranceExamData || {};
|
||||
const isActiveEntranceExam = entranceExamEnabled && !entranceExamPassed;
|
||||
|
||||
const handleToggleCollapse = () => {
|
||||
if (currentSidebar === ID) {
|
||||
toggleSidebar(null);
|
||||
window.sessionStorage.setItem('hideCourseOutlineSidebar', 'true');
|
||||
} else {
|
||||
toggleSidebar(ID);
|
||||
window.sessionStorage.removeItem('hideCourseOutlineSidebar');
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpenSidebar && currentSidebar !== ID) {
|
||||
toggleSidebar(ID);
|
||||
}
|
||||
}, [initialSidebar, unitId]);
|
||||
|
||||
return {
|
||||
courseId,
|
||||
unitId,
|
||||
currentSidebar,
|
||||
shouldDisplayFullScreen,
|
||||
isEnabledSidebar,
|
||||
isOpen,
|
||||
setIsOpen,
|
||||
handleToggleCollapse,
|
||||
isActiveEntranceExam,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const DashedCircleIcon = (props) => (
|
||||
<svg
|
||||
width={24}
|
||||
height={24}
|
||||
viewBox="0 0 40 40"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
>
|
||||
<circle
|
||||
cx="20"
|
||||
cy="20"
|
||||
r="15"
|
||||
stroke="#ccc"
|
||||
strokeWidth="3"
|
||||
strokeDasharray="2.6 2.3"
|
||||
fill="transparent"
|
||||
strokeDashoffset="27"
|
||||
/>
|
||||
<circle
|
||||
cx="20"
|
||||
cy="20"
|
||||
r="15"
|
||||
fill="transparent"
|
||||
stroke="#0d7d4d"
|
||||
strokeWidth="3"
|
||||
strokeDasharray={`${props.percentage} ${props.remainder}`}
|
||||
strokeDashoffset="29"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
DashedCircleIcon.propTypes = {
|
||||
percentage: PropTypes.number.isRequired,
|
||||
remainder: PropTypes.number.isRequired,
|
||||
};
|
||||
|
||||
export default DashedCircleIcon;
|
||||
@@ -0,0 +1,2 @@
|
||||
// eslint-disable-next-line import/prefer-default-export
|
||||
export { default as DashedCircleIcon } from './DashedCircleIcon';
|
||||
@@ -0,0 +1,3 @@
|
||||
export { default as Sidebar } from './CourseOutlineTray';
|
||||
export { default as Trigger } from './CourseOutlineTrigger';
|
||||
export { ID } from './constants';
|
||||
@@ -0,0 +1,31 @@
|
||||
import { defineMessages } from '@edx/frontend-platform/i18n';
|
||||
|
||||
const messages = defineMessages({
|
||||
loading: {
|
||||
id: 'courseOutline.loading',
|
||||
defaultMessage: 'Loading...',
|
||||
description: 'Screen reader text to use on the spinner while the sidebar is loading.',
|
||||
},
|
||||
toggleCourseOutlineTrigger: {
|
||||
id: 'courseOutline.toggle.button',
|
||||
defaultMessage: 'Toggle course outline tray',
|
||||
description: 'Button for the learner to toggle the sidebar',
|
||||
},
|
||||
courseOutlineTitle: {
|
||||
id: 'courseOutline.tray.title',
|
||||
defaultMessage: 'Course Outline',
|
||||
description: 'Title text displayed for the course outline tray',
|
||||
},
|
||||
completedUnit: {
|
||||
id: 'courseOutline.completedUnit',
|
||||
defaultMessage: 'Completed unit',
|
||||
description: 'Text used to describe the green checkmark icon in front of a unit title',
|
||||
},
|
||||
incompleteUnit: {
|
||||
id: 'courseOutline.incompleteUnit',
|
||||
defaultMessage: 'Incomplete unit',
|
||||
description: 'Text used to describe the gray checkmark icon in front of a unit title',
|
||||
},
|
||||
});
|
||||
|
||||
export default messages;
|
||||
@@ -0,0 +1,5 @@
|
||||
.discussions-sidebar-frame {
|
||||
@media (max-width: -1 + map-get($grid-breakpoints, "xl")) {
|
||||
max-height: calc(100vh - 65px);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
import { useContext } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { ensureConfig, getConfig } from '@edx/frontend-platform';
|
||||
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
|
||||
import React, { useContext } from 'react';
|
||||
import { useModel } from '../../../../../generic/model-store';
|
||||
|
||||
import { useModel } from '@src/generic/model-store';
|
||||
import SidebarBase from '../../common/SidebarBase';
|
||||
import SidebarContext from '../../SidebarContext';
|
||||
import { ID } from './DiscussionsTrigger';
|
||||
@@ -14,6 +16,7 @@ const DiscussionsSidebar = ({ intl }) => {
|
||||
const {
|
||||
unitId,
|
||||
courseId,
|
||||
shouldDisplayFullScreen,
|
||||
} = useContext(SidebarContext);
|
||||
const topic = useModel('discussionTopics', unitId);
|
||||
const discussionsUrl = `${getConfig().DISCUSSIONS_MFE_BASE_URL}/${courseId}/category/${unitId}`;
|
||||
@@ -27,12 +30,15 @@ const DiscussionsSidebar = ({ intl }) => {
|
||||
title={intl.formatMessage(messages.discussionsTitle)}
|
||||
ariaLabel={intl.formatMessage(messages.discussionsTitle)}
|
||||
sidebarId={ID}
|
||||
width="50rem"
|
||||
width="45rem"
|
||||
showTitleBar={false}
|
||||
className={classNames({
|
||||
'ml-4': !shouldDisplayFullScreen,
|
||||
})}
|
||||
>
|
||||
<iframe
|
||||
src={`${discussionsUrl}?inContextSidebar`}
|
||||
className="d-flex sticky-top vh-100 w-100 border-0"
|
||||
className="d-flex sticky-top vh-100 w-100 border-0 discussions-sidebar-frame"
|
||||
title={intl.formatMessage(messages.discussionsTitle)}
|
||||
allow="clipboard-write"
|
||||
loading="lazy"
|
||||
|
||||
@@ -3,16 +3,17 @@ import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
|
||||
import { Icon } from '@openedx/paragon';
|
||||
import { QuestionAnswer } from '@openedx/paragon/icons';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { useContext, useEffect, useMemo } from 'react';
|
||||
import { useContext, useEffect, useMemo } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { useModel } from '../../../../../generic/model-store';
|
||||
import { useModel } from '@src/generic/model-store';
|
||||
import { WIDGETS } from '@src/constants';
|
||||
import { getCourseDiscussionTopics } from '../../../../data/thunks';
|
||||
import SidebarTriggerBase from '../../common/TriggerBase';
|
||||
import SidebarContext from '../../SidebarContext';
|
||||
import messages from './messages';
|
||||
|
||||
ensureConfig(['DISCUSSIONS_MFE_BASE_URL']);
|
||||
export const ID = 'DISCUSSIONS';
|
||||
export const ID = WIDGETS.DISCUSSIONS;
|
||||
|
||||
const DiscussionsTrigger = ({
|
||||
intl,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
|
||||
import classNames from 'classnames';
|
||||
import React, { useContext, useEffect, useMemo } from 'react';
|
||||
import { useContext, useEffect, useMemo } from 'react';
|
||||
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
|
||||
import { useModel } from '../../../../../generic/model-store';
|
||||
import UpgradeNotification from '../../../../../generic/upgrade-notification/UpgradeNotification';
|
||||
import { useModel } from '@src/generic/model-store';
|
||||
import UpgradeNotification from '@src/generic/upgrade-notification/UpgradeNotification';
|
||||
|
||||
import messages from '../../../messages';
|
||||
import SidebarBase from '../../common/SidebarBase';
|
||||
@@ -70,8 +70,10 @@ const NotificationTray = ({ intl }) => {
|
||||
title={intl.formatMessage(messages.notificationTitle)}
|
||||
ariaLabel={intl.formatMessage(messages.notificationTray)}
|
||||
sidebarId={ID}
|
||||
width="50rem"
|
||||
className={classNames({ 'h-100': !verifiedMode && !shouldDisplayFullScreen })}
|
||||
className={classNames({
|
||||
'h-100': !verifiedMode && !shouldDisplayFullScreen,
|
||||
'ml-4': !shouldDisplayFullScreen,
|
||||
})}
|
||||
>
|
||||
<div>{verifiedMode
|
||||
? (
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import { useContext, useEffect } from 'react';
|
||||
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { useContext, useEffect } from 'react';
|
||||
import { getLocalStorage, setLocalStorage } from '../../../../../data/localStorage';
|
||||
|
||||
import { WIDGETS } from '@src/constants';
|
||||
import { getLocalStorage, setLocalStorage } from '@src/data/localStorage';
|
||||
import messages from '../../../messages';
|
||||
import SidebarTriggerBase from '../../common/TriggerBase';
|
||||
import SidebarContext from '../../SidebarContext';
|
||||
|
||||
import NotificationIcon from './NotificationIcon';
|
||||
|
||||
export const ID = 'NOTIFICATIONS';
|
||||
export const ID = WIDGETS.NOTIFICATIONS;
|
||||
|
||||
const NotificationTrigger = ({
|
||||
intl,
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import React from 'react';
|
||||
import { Factory } from 'rosie';
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import { getConfig, snakeCaseObject } from '@edx/frontend-platform';
|
||||
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
|
||||
import MockAdapter from 'axios-mock-adapter';
|
||||
import { breakpoints } from '@openedx/paragon';
|
||||
import { initializeTestStore, render } from '../../setupTest';
|
||||
import { executeThunk } from '@src/utils';
|
||||
import { initializeTestStore, render } from '@src/setupTest';
|
||||
import SidebarContext from '@src/courseware/course/sidebar/SidebarContext';
|
||||
import { buildTopicsFromUnits } from '../data/__factories__/discussionTopics.factory';
|
||||
import { executeThunk } from '../../utils';
|
||||
import * as thunks from '../data/thunks';
|
||||
import Course from './Course';
|
||||
|
||||
@@ -16,7 +17,8 @@ const mockData = {
|
||||
unitNavigationHandler: () => {},
|
||||
};
|
||||
|
||||
const setupDiscussionSidebar = async (verifiedMode = null, enabledInContext = true) => {
|
||||
const setupDiscussionSidebar = async (HomeMetaParams) => {
|
||||
const params = { verifiedMode: null, enabledInContext: true, ...HomeMetaParams };
|
||||
const store = await initializeTestStore();
|
||||
const { courseware, models } = store.getState();
|
||||
const { courseId, sequenceId } = courseware;
|
||||
@@ -25,14 +27,14 @@ const setupDiscussionSidebar = async (verifiedMode = null, enabledInContext = tr
|
||||
sequenceId,
|
||||
unitId: Object.values(models.units)[0].id,
|
||||
});
|
||||
global.innerWidth = breakpoints.extraLarge.minWidth;
|
||||
global.innerWidth = breakpoints.extraExtraLarge.minWidth;
|
||||
|
||||
const courseHomeMetadata = Factory.build('courseHomeMetadata', { verified_mode: verifiedMode });
|
||||
const courseHomeMetadata = Factory.build('courseHomeMetadata', { ...snakeCaseObject(params) });
|
||||
const testStore = await initializeTestStore({ provider: 'openedx', courseHomeMetadata });
|
||||
const state = testStore.getState();
|
||||
const axiosMock = new MockAdapter(getAuthenticatedHttpClient());
|
||||
axiosMock.onGet(`${getConfig().LMS_BASE_URL}/api/discussion/v1/courses/${courseId}`).reply(200, { provider: 'openedx' });
|
||||
const topicsResponse = buildTopicsFromUnits(state.models.units, enabledInContext);
|
||||
const topicsResponse = buildTopicsFromUnits(state.models.units, params.enabledInContext);
|
||||
axiosMock.onGet(`${getConfig().LMS_BASE_URL}/api/discussion/v2/course_topics/${courseId}`)
|
||||
.reply(200, topicsResponse);
|
||||
|
||||
@@ -41,8 +43,14 @@ const setupDiscussionSidebar = async (verifiedMode = null, enabledInContext = tr
|
||||
mockData.unitId = firstUnitId;
|
||||
const [firstSequenceId] = Object.keys(state.models.sequences);
|
||||
mockData.sequenceId = firstSequenceId;
|
||||
const contextValue = { courseId: mockData.courseId, currentSidebar: null, toggleSidebar: jest.fn() };
|
||||
|
||||
const wrapper = await render(<Course {...mockData} />, { store: testStore, wrapWithRouter: true });
|
||||
const wrapper = await render(
|
||||
<SidebarContext.Provider value={contextValue}>
|
||||
<Course {...mockData} />
|
||||
</SidebarContext.Provider>,
|
||||
{ store: testStore, wrapWithRouter: true },
|
||||
);
|
||||
return wrapper;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,71 +1,9 @@
|
||||
import { camelCaseObject, getConfig } from '@edx/frontend-platform';
|
||||
import { getAuthenticatedHttpClient, getAuthenticatedUser } from '@edx/frontend-platform/auth';
|
||||
import { getTimeOffsetMillis } from '../../course-home/data/api';
|
||||
import { appendBrowserTimezoneToUrl } from '../../utils';
|
||||
|
||||
export function normalizeLearningSequencesData(learningSequencesData) {
|
||||
const models = {
|
||||
courses: {},
|
||||
sections: {},
|
||||
sequences: {},
|
||||
};
|
||||
|
||||
const now = new Date();
|
||||
function isReleased(block) {
|
||||
// We check whether the backend marks this as accessible because staff users are granted access anyway.
|
||||
// Note that sections don't have the `accessible` field and will just be checking `effective_start`.
|
||||
return block.accessible || !block.effective_start || now >= Date.parse(block.effective_start);
|
||||
}
|
||||
|
||||
// Sequences
|
||||
Object.entries(learningSequencesData.outline.sequences).forEach(([seqId, sequence]) => {
|
||||
if (!isReleased(sequence)) {
|
||||
return; // Don't let the learner see unreleased sequences
|
||||
}
|
||||
|
||||
models.sequences[seqId] = {
|
||||
id: seqId,
|
||||
title: sequence.title,
|
||||
};
|
||||
});
|
||||
|
||||
// Sections
|
||||
learningSequencesData.outline.sections.forEach(section => {
|
||||
// Filter out any ignored sequences (e.g. unreleased sequences)
|
||||
const availableSequenceIds = section.sequence_ids.filter(seqId => seqId in models.sequences);
|
||||
|
||||
// If we are unreleased and already stripped out all our children, just don't show us at all.
|
||||
// (We check both release date and children because children will exist for an unreleased section even for staff,
|
||||
// so we still want to show this section.)
|
||||
if (!isReleased(section) && availableSequenceIds.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
models.sections[section.id] = {
|
||||
id: section.id,
|
||||
title: section.title,
|
||||
sequenceIds: availableSequenceIds,
|
||||
courseId: learningSequencesData.course_key,
|
||||
};
|
||||
|
||||
// Add back-references to this section for all child sequences.
|
||||
availableSequenceIds.forEach(childSeqId => {
|
||||
models.sequences[childSeqId].sectionId = section.id;
|
||||
});
|
||||
});
|
||||
|
||||
// Course
|
||||
models.courses[learningSequencesData.course_key] = {
|
||||
id: learningSequencesData.course_key,
|
||||
title: learningSequencesData.title,
|
||||
sectionIds: Object.entries(models.sections).map(([sectionId]) => sectionId),
|
||||
|
||||
// Scan through all the sequences and look for ones that aren't released yet.
|
||||
hasScheduledContent: Object.values(learningSequencesData.outline.sequences).some(seq => !isReleased(seq)),
|
||||
};
|
||||
|
||||
return models;
|
||||
}
|
||||
import {
|
||||
normalizeLearningSequencesData, normalizeMetadata, normalizeOutlineBlocks, normalizeSequenceMetadata,
|
||||
} from './utils';
|
||||
|
||||
// Do not add further calls to this API - we don't like making use of the modulestore if we can help it
|
||||
export async function getSequenceForUnitDeprecated(courseId, unitId) {
|
||||
@@ -87,46 +25,6 @@ export async function getLearningSequencesOutline(courseId) {
|
||||
return normalizeLearningSequencesData(data);
|
||||
}
|
||||
|
||||
function normalizeMetadata(metadata) {
|
||||
const requestTime = Date.now();
|
||||
const responseTime = requestTime;
|
||||
const { data, headers } = metadata;
|
||||
return {
|
||||
accessExpiration: camelCaseObject(data.access_expiration),
|
||||
canShowUpgradeSock: data.can_show_upgrade_sock,
|
||||
contentTypeGatingEnabled: data.content_type_gating_enabled,
|
||||
courseGoals: camelCaseObject(data.course_goals),
|
||||
id: data.id,
|
||||
title: data.name,
|
||||
offer: camelCaseObject(data.offer),
|
||||
enrollmentStart: data.enrollment_start,
|
||||
enrollmentEnd: data.enrollment_end,
|
||||
end: data.end,
|
||||
start: data.start,
|
||||
enrollmentMode: data.enrollment.mode,
|
||||
isEnrolled: data.enrollment.is_active,
|
||||
license: data.license,
|
||||
userTimezone: data.user_timezone,
|
||||
showCalculator: data.show_calculator,
|
||||
notes: camelCaseObject(data.notes),
|
||||
marketingUrl: data.marketing_url,
|
||||
celebrations: camelCaseObject(data.celebrations),
|
||||
userHasPassingGrade: data.user_has_passing_grade,
|
||||
courseExitPageIsActive: data.course_exit_page_is_active,
|
||||
certificateData: camelCaseObject(data.certificate_data),
|
||||
entranceExamData: camelCaseObject(data.entrance_exam_data),
|
||||
language: data.language,
|
||||
timeOffsetMillis: getTimeOffsetMillis(headers && headers.date, requestTime, responseTime),
|
||||
verifyIdentityUrl: data.verify_identity_url,
|
||||
verificationStatus: data.verification_status,
|
||||
linkedinAddToProfileUrl: data.linkedin_add_to_profile_url,
|
||||
relatedPrograms: camelCaseObject(data.related_programs),
|
||||
userNeedsIntegritySignature: data.user_needs_integrity_signature,
|
||||
canAccessProctoredExams: data.can_access_proctored_exams,
|
||||
learningAssistantEnabled: data.learning_assistant_enabled,
|
||||
};
|
||||
}
|
||||
|
||||
export async function getCourseMetadata(courseId) {
|
||||
let url = `${getConfig().LMS_BASE_URL}/api/courseware/course/${courseId}`;
|
||||
url = appendBrowserTimezoneToUrl(url);
|
||||
@@ -134,48 +32,6 @@ export async function getCourseMetadata(courseId) {
|
||||
return normalizeMetadata(metadata);
|
||||
}
|
||||
|
||||
function normalizeSequenceMetadata(sequence) {
|
||||
return {
|
||||
sequence: {
|
||||
id: sequence.item_id,
|
||||
blockType: sequence.tag,
|
||||
unitIds: sequence.items.map(unit => unit.id),
|
||||
bannerText: sequence.banner_text,
|
||||
format: sequence.format,
|
||||
title: sequence.display_name,
|
||||
/*
|
||||
Example structure of gated_content when prerequisites exist:
|
||||
{
|
||||
prereq_id: 'id of the prereq section',
|
||||
prereq_url: 'unused by this frontend',
|
||||
prereq_section_name: 'Name of the prerequisite section',
|
||||
gated: true,
|
||||
gated_section_name: 'Name of this gated section',
|
||||
*/
|
||||
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,
|
||||
showCompletion: sequence.show_completion,
|
||||
allowProctoringOptOut: sequence.allow_proctoring_opt_out,
|
||||
navigationDisabled: sequence.navigation_disabled,
|
||||
},
|
||||
units: sequence.items.map(unit => ({
|
||||
id: unit.id,
|
||||
sequenceId: sequence.item_id,
|
||||
bookmarked: unit.bookmarked,
|
||||
complete: unit.complete,
|
||||
title: unit.page_title,
|
||||
contentType: unit.type,
|
||||
graded: unit.graded,
|
||||
containsContentTypeGatedContent: unit.contains_content_type_gated_content,
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
export async function getSequenceMetadata(sequenceId) {
|
||||
const { data } = await getAuthenticatedHttpClient()
|
||||
.get(`${getConfig().LMS_BASE_URL}/api/courseware/sequence/${sequenceId}`, {});
|
||||
@@ -230,3 +86,30 @@ export async function getCourseTopics(courseId) {
|
||||
.get(`${getConfig().LMS_BASE_URL}/api/discussion/v2/course_topics/${courseId}`);
|
||||
return camelCaseObject(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get course outline structure for the courseware navigation sidebar.
|
||||
* @param {string} courseId - The unique identifier for the course.
|
||||
* @returns {Promise<{units: {}, sequences: {}, sections: {}}|null>}
|
||||
*/
|
||||
export async function getCourseOutline(courseId) {
|
||||
const { data } = await getAuthenticatedHttpClient()
|
||||
.get(`${getConfig().LMS_BASE_URL}/api/course_home/v1/navigation/${courseId}`);
|
||||
|
||||
return data.blocks ? normalizeOutlineBlocks(courseId, data.blocks) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get waffle flag value that enable courseware outline sidebar and always open auxiliary sidebar.
|
||||
* @param {string} courseId - The unique identifier for the course.
|
||||
* @returns {Promise<{enable_navigation_sidebar: boolean, enable_navigation_sidebar: boolean}>} - The object
|
||||
* of boolean values of enabling of the outline sidebar and is always open auxiliary sidebar.
|
||||
*/
|
||||
export async function getCoursewareOutlineSidebarToggles(courseId) {
|
||||
const url = new URL(`${getConfig().LMS_BASE_URL}/courses/${courseId}/courseware-navigation-sidebar/toggles/`);
|
||||
const { data } = await getAuthenticatedHttpClient().get(url.href);
|
||||
return {
|
||||
enable_navigation_sidebar: data.enable_navigation_sidebar || false,
|
||||
always_open_auxiliary_sidebar: data.always_open_auxiliary_sidebar || false,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
|
||||
import * as thunks from './thunks';
|
||||
import { FAILED, LOADING } from './slice';
|
||||
|
||||
import { appendBrowserTimezoneToUrl, executeThunk } from '../../utils';
|
||||
|
||||
@@ -43,6 +44,7 @@ describe('Data layer integration tests', () => {
|
||||
const sequenceUrl = `${sequenceBaseUrl}/${sequenceMetadata.item_id}`;
|
||||
const sequenceId = sequenceBlocks[0].id;
|
||||
const unitId = unitBlocks[0].id;
|
||||
const coursewareSidebarSettingsUrl = `${getConfig().LMS_BASE_URL}/courses/${courseId}/courseware-navigation-sidebar/toggles/`;
|
||||
|
||||
let store;
|
||||
|
||||
@@ -57,13 +59,20 @@ describe('Data layer integration tests', () => {
|
||||
it('Should fail to fetch course and blocks if request error happens', async () => {
|
||||
axiosMock.onGet(courseUrl).networkError();
|
||||
axiosMock.onGet(learningSequencesUrlRegExp).networkError();
|
||||
axiosMock.onGet(coursewareSidebarSettingsUrl).networkError();
|
||||
|
||||
await executeThunk(thunks.fetchCourse(courseId), store.dispatch);
|
||||
|
||||
expect(loggingService.logError).toHaveBeenCalled();
|
||||
expect(store.getState().courseware).toEqual(expect.objectContaining({
|
||||
courseId,
|
||||
courseStatus: 'failed',
|
||||
courseOutline: {},
|
||||
courseStatus: FAILED,
|
||||
coursewareOutlineSidebarSettings: {},
|
||||
courseOutlineStatus: LOADING,
|
||||
sequenceId: null,
|
||||
sequenceMightBeUnit: false,
|
||||
sequenceStatus: LOADING,
|
||||
}));
|
||||
});
|
||||
|
||||
@@ -101,6 +110,10 @@ describe('Data layer integration tests', () => {
|
||||
axiosMock.onGet(courseHomeMetadataUrl).reply(200, courseHomeMetadata);
|
||||
axiosMock.onGet(courseUrl).reply(200, courseMetadata);
|
||||
axiosMock.onGet(learningSequencesUrlRegExp).reply(200, buildOutlineFromBlocks(courseBlocks));
|
||||
axiosMock.onGet(coursewareSidebarSettingsUrl).reply(200, {
|
||||
enable_navigation_sidebar: true,
|
||||
always_open_auxiliary_sidebar: true,
|
||||
});
|
||||
|
||||
await executeThunk(thunks.fetchCourse(courseId), store.dispatch);
|
||||
|
||||
@@ -110,6 +123,10 @@ describe('Data layer integration tests', () => {
|
||||
expect(state.courseware.courseId).toEqual(courseId);
|
||||
expect(state.courseware.sequenceStatus).toEqual('loading');
|
||||
expect(state.courseware.sequenceId).toEqual(null);
|
||||
expect(state.courseware.coursewareOutlineSidebarSettings).toEqual({
|
||||
enableNavigationSidebar: true,
|
||||
alwaysOpenAuxiliarySidebar: true,
|
||||
});
|
||||
|
||||
// check that at least one key camel cased, thus course data normalized
|
||||
expect(state.models.coursewareMeta[courseId].marketingUrl).not.toBeUndefined();
|
||||
@@ -121,6 +138,10 @@ describe('Data layer integration tests', () => {
|
||||
axiosMock.onGet(courseHomeMetadataUrl).reply(200, courseHomeMetadata);
|
||||
axiosMock.onGet(courseUrl).reply(200, courseMetadata);
|
||||
axiosMock.onGet(learningSequencesUrlRegExp).reply(200, simpleOutline);
|
||||
axiosMock.onGet(coursewareSidebarSettingsUrl).reply(200, {
|
||||
enable_navigation_sidebar: false,
|
||||
always_open_auxiliary_sidebar: false,
|
||||
});
|
||||
|
||||
await executeThunk(thunks.fetchCourse(courseId), store.dispatch);
|
||||
|
||||
@@ -130,6 +151,10 @@ describe('Data layer integration tests', () => {
|
||||
expect(state.courseware.courseId).toEqual(courseId);
|
||||
expect(state.courseware.sequenceStatus).toEqual('loading');
|
||||
expect(state.courseware.sequenceId).toEqual(null);
|
||||
expect(state.courseware.coursewareOutlineSidebarSettings).toEqual({
|
||||
enableNavigationSidebar: false,
|
||||
alwaysOpenAuxiliarySidebar: false,
|
||||
});
|
||||
|
||||
// check that at least one key camel cased, thus course data normalized
|
||||
expect(state.models.coursewareMeta[courseId].marketingUrl).not.toBeUndefined();
|
||||
@@ -254,31 +279,74 @@ describe('Data layer integration tests', () => {
|
||||
});
|
||||
|
||||
describe('Test checkBlockCompletion', () => {
|
||||
const getCourseOutlineURL = `${getConfig().LMS_BASE_URL}/api/course_home/v1/navigation/${courseId}`;
|
||||
const getCompletionURL = `${getConfig().LMS_BASE_URL}/courses/${courseId}/xblock/${sequenceId}/handler/get_completion`;
|
||||
|
||||
it('Should fail to check completion and log error', async () => {
|
||||
axiosMock.onPost(getCompletionURL).networkError();
|
||||
axiosMock.onGet(getCourseOutlineURL).networkError();
|
||||
|
||||
await executeThunk(
|
||||
thunks.checkBlockCompletion(courseId, sequenceId, unitId),
|
||||
store.dispatch,
|
||||
store.getState,
|
||||
);
|
||||
await executeThunk(
|
||||
thunks.getCourseOutlineStructure(courseId, sequenceId, unitId),
|
||||
store.dispatch,
|
||||
store.getState,
|
||||
);
|
||||
|
||||
expect(loggingService.logError).toHaveBeenCalled();
|
||||
expect(axiosMock.history.post[0].url).toEqual(getCompletionURL);
|
||||
});
|
||||
|
||||
it('Should update complete field of unit model', async () => {
|
||||
it('Should update complete field of unit model and course outline', async () => {
|
||||
axiosMock.onPost(getCompletionURL).reply(201, { complete: true });
|
||||
axiosMock.onGet(getCourseOutlineURL).reply(201, {
|
||||
...courseBlocks,
|
||||
...sequenceBlocks,
|
||||
...unitBlocks,
|
||||
});
|
||||
|
||||
await executeThunk(
|
||||
thunks.checkBlockCompletion(courseId, sequenceId, unitId),
|
||||
store.dispatch,
|
||||
store.getState,
|
||||
);
|
||||
await executeThunk(thunks.getCourseOutlineStructure(courseId), store.dispatch, store.getState);
|
||||
|
||||
expect(store.getState().models.units[unitId].complete).toBeTruthy();
|
||||
const [unit] = Object.values(store.getState().courseware.courseOutline.units);
|
||||
const [sequence] = Object.values(store.getState().courseware.courseOutline.sequences);
|
||||
const [section] = Object.values(store.getState().courseware.courseOutline.sections);
|
||||
|
||||
expect(unit.complete).not.toBeTruthy();
|
||||
expect(sequence.complete).not.toBeTruthy();
|
||||
expect(section.complete).not.toBeTruthy();
|
||||
|
||||
await executeThunk(thunks.checkBlockCompletion(courseId, sequenceId, unit.id), store.dispatch, store.getState);
|
||||
|
||||
expect(store.getState().models.units[unit.id].complete).toBeTruthy();
|
||||
expect(store.getState().courseware.courseOutline.units[unit.id].complete).toBeTruthy();
|
||||
expect(store.getState().courseware.courseOutline.sequences[sequence.id].complete).toBeTruthy();
|
||||
expect(store.getState().courseware.courseOutline.sections[section.id].complete).toBeTruthy();
|
||||
});
|
||||
|
||||
it('Shouldn\'t update complete field if complete is false', async () => {
|
||||
axiosMock.onPost(getCompletionURL).reply(201, { complete: false });
|
||||
axiosMock.onGet(getCourseOutlineURL).reply(201, {
|
||||
...courseBlocks,
|
||||
...sequenceBlocks,
|
||||
...unitBlocks,
|
||||
});
|
||||
|
||||
await executeThunk(thunks.getCourseOutlineStructure(courseId), store.dispatch, store.getState);
|
||||
|
||||
const [unit] = Object.values(store.getState().courseware.courseOutline.units);
|
||||
const [sequence] = Object.values(store.getState().courseware.courseOutline.sequences);
|
||||
const [section] = Object.values(store.getState().courseware.courseOutline.sections);
|
||||
|
||||
await executeThunk(thunks.checkBlockCompletion(courseId, sequenceId, unit.id), store.dispatch, store.getState);
|
||||
|
||||
expect(store.getState().models.units[unit.id].complete).not.toBeTruthy();
|
||||
expect(store.getState().courseware.courseOutline.units[unit.id].complete).not.toBeTruthy();
|
||||
expect(store.getState().courseware.courseOutline.sequences[sequence.id].complete).not.toBeTruthy();
|
||||
expect(store.getState().courseware.courseOutline.sections[section.id].complete).not.toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,12 +1,21 @@
|
||||
/* eslint-disable import/prefer-default-export */
|
||||
import { LOADED } from './slice';
|
||||
|
||||
export function sequenceIdsSelector(state) {
|
||||
if (state.courseware.courseStatus !== 'loaded') {
|
||||
if (state.courseware.courseStatus !== LOADED) {
|
||||
return [];
|
||||
}
|
||||
const { sectionIds = [] } = state.models.coursewareMeta[state.courseware.courseId];
|
||||
|
||||
const sequenceIds = sectionIds
|
||||
return sectionIds
|
||||
.flatMap(sectionId => state.models.sections[sectionId].sequenceIds);
|
||||
|
||||
return sequenceIds;
|
||||
}
|
||||
|
||||
export const getSequenceId = state => state.courseware.sequenceId;
|
||||
|
||||
export const getCourseOutline = state => state.courseware.courseOutline;
|
||||
|
||||
export const getCourseOutlineStatus = state => state.courseware.courseOutlineStatus;
|
||||
|
||||
export const getCoursewareOutlineSidebarSettings = state => state.courseware.coursewareOutlineSidebarSettings;
|
||||
|
||||
export const getCourseOutlineShouldUpdate = state => state.courseware.courseOutlineShouldUpdate;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user