diff --git a/babel.config.json b/babel.config.json index 76acd15661c..7c5e8995c90 100644 --- a/babel.config.json +++ b/babel.config.json @@ -25,12 +25,16 @@ ], "plugins": [ "@babel/plugin-syntax-dynamic-import", - "react-hot-loader/babel", [ "@babel/plugin-proposal-class-properties", { "loose": true } ] - ] + ], + "env": { + "development": { + "plugins": ["react-refresh/babel"] + } + } } diff --git a/package.json b/package.json index 7821e680cba..0bd1acf443e 100644 --- a/package.json +++ b/package.json @@ -46,10 +46,9 @@ "react-bootstrap": "2.10.10", "react-dates": "21.8.0", "react-dom": "18.3.1", - "react-helmet": "6.1.0", + "react-helmet-async": "2.0.5", "react-highlight-words": "0.20.0", "react-hot-keys": "2.7.3", - "react-hot-loader": "4.13.1", "react-lazylog": "4.5.3", "react-linkify": "0.2.2", "react-redux": "8.0.7", @@ -78,6 +77,7 @@ "@babel/plugin-syntax-dynamic-import": "7.8.3", "@babel/preset-env": "7.26.9", "@babel/preset-react": "7.27.1", + "@pmmmwh/react-refresh-webpack-plugin": "0.6.1", "@pollyjs/adapter-fetch": "6.0.7", "@pollyjs/adapter-node-http": "6.0.6", "@pollyjs/adapter-puppeteer": "6.0.6", @@ -113,6 +113,7 @@ "path": "0.12.7", "prettier": "2.2.1", "puppeteer": "24.2.1", + "react-refresh": "0.17.0", "sass": "1.93.2", "sass-loader": "16.0.6", "setup-polly-jest": "0.11.0", diff --git a/tests/ui/push-health/Health_test.jsx b/tests/ui/push-health/Health_test.jsx index 3bb4825045c..8cf2f11b2c2 100644 --- a/tests/ui/push-health/Health_test.jsx +++ b/tests/ui/push-health/Health_test.jsx @@ -10,6 +10,7 @@ import { import { createBrowserHistory } from 'history'; import { ConnectedRouter } from 'connected-react-router'; import { Provider } from 'react-redux'; +import { HelmetProvider } from 'react-helmet-async'; import Health from '../../../ui/push-health/Health'; import pushHealth from '../mock/push_health'; @@ -126,15 +127,17 @@ describe('Health', () => { const testHealth = () => { const store = configureStore(history); return ( - - - {}} - clearNotification={() => {}} - /> - - + + + + {}} + clearNotification={() => {}} + /> + + + ); }; diff --git a/tests/ui/push-health/MyPushes_test.jsx b/tests/ui/push-health/MyPushes_test.jsx index 5c94a81897b..be0ce027f3e 100644 --- a/tests/ui/push-health/MyPushes_test.jsx +++ b/tests/ui/push-health/MyPushes_test.jsx @@ -4,6 +4,7 @@ import { render, waitFor, fireEvent } from '@testing-library/react'; import { createBrowserHistory } from 'history'; import { ConnectedRouter } from 'connected-react-router'; import { Provider } from 'react-redux'; +import { HelmetProvider } from 'react-helmet-async'; import MyPushes from '../../../ui/push-health/MyPushes'; import pushHealthSummaryTryData from '../mock/push_health_summary_try'; @@ -35,17 +36,19 @@ describe('My Pushes', () => { const testMyPushes = (user = testUser) => { const store = configureStore(history); return ( - - - {}} - clearNotification={() => {}} - history={history} - /> - - + + + + {}} + clearNotification={() => {}} + history={history} + /> + + + ); }; diff --git a/ui/App.jsx b/ui/App.jsx index 2f528d15990..3fd9722577c 100644 --- a/ui/App.jsx +++ b/ui/App.jsx @@ -1,8 +1,8 @@ import React, { Suspense, lazy } from 'react'; import { Route, Switch } from 'react-router-dom'; -import { hot } from 'react-hot-loader/root'; import { ConnectedRouter } from 'connected-react-router'; import { Provider } from 'react-redux'; +import { HelmetProvider } from 'react-helmet-async'; import { permaLinkPrefix } from './perfherder/perf-helpers/constants'; import { configureStore, history } from './job-view/redux/configureStore'; @@ -118,71 +118,76 @@ const withFavicon = (element, route) => { const App = () => { updateUrls(); return ( - - - }> - - } - /> - } - /> - - withFavicon(, props.location.pathname) - } - /> - - withFavicon( - , - props.location.pathname, - ) - } - /> - - withFavicon( - , - props.location.pathname, - ) - } - /> - - withFavicon(, '/push-health') - } - /> - - withFavicon( - , - '/intermittent-failures', - ) - } - /> - - withFavicon(, '/perfherder') - } - /> - } /> - - - - + + + + }> + + } + /> + } + /> + + withFavicon( + , + props.location.pathname, + ) + } + /> + + withFavicon( + , + props.location.pathname, + ) + } + /> + + withFavicon( + , + props.location.pathname, + ) + } + /> + + withFavicon(, '/push-health') + } + /> + + withFavicon( + , + '/intermittent-failures', + ) + } + /> + + withFavicon(, '/perfherder') + } + /> + } /> + + + + + ); }; -export default hot(App); +export default App; diff --git a/ui/css/bootstrap-custom.scss b/ui/css/bootstrap-custom.scss index c4b2e410a4c..b730480e458 100644 --- a/ui/css/bootstrap-custom.scss +++ b/ui/css/bootstrap-custom.scss @@ -1,76 +1,71 @@ // Treeherder Bootstrap 5 Customization // This file sets global variables before Bootstrap is imported +// Using @use instead of deprecated @import (Dart Sass 3.0 compatibility) -// Typography - Use browser default 16px to match production -$font-size-root: null; // Use browser default 16px root font size -$font-size-base: 1rem; // 16px (match production) -$font-size-sm: 0.875rem; // 14px -$font-size-lg: 1.25rem; // 20px +// Forward our customizations to Bootstrap using @use with configuration +@use 'sass:map'; -// Font family - Match production -$font-family-sans-serif: 'Helvetica Neue', Helvetica, Arial, sans-serif; +// Bootstrap 5 customization via @use ... with () +@use '~bootstrap/scss/bootstrap' with ( + // Typography - Use browser default 16px to match production + $font-size-root: null, + $font-size-base: 1rem, + $font-size-sm: 0.875rem, + $font-size-lg: 1.25rem, -// Line heights -$line-height-base: 1.42857143; // Match previous Treeherder line height (19.88px at 14px font) + // Font family - Match production + $font-family-sans-serif: ('Helvetica Neue', Helvetica, Arial, sans-serif), -// Spacing scale - maintain existing spacing -$spacer: 1rem; -$spacers: ( - 0: 0, - 1: $spacer * 0.25, - // 0.25rem = 4px - 2: $spacer * 0.5, - // 0.5rem = 8px - 3: $spacer * 0.75, - // 0.75rem = 12px - 4: $spacer, - // 1rem = 16px - 5: $spacer * 1.5, - // 1.5rem = 24px - 6: $spacer * 7.5, - // 7.5rem = 120px -); - -// Buttons - maintain original sizing -$btn-padding-y: 0.375rem; -$btn-padding-x: 0.75rem; -$btn-font-size: $font-size-base; -$btn-line-height: 1.5; - -$btn-padding-y-sm: 0.25rem; -$btn-padding-x-sm: 0.5rem; -$btn-font-size-sm: $font-size-sm; // 12px + // Line heights + $line-height-base: 1.42857143, -$btn-padding-y-lg: 0.5rem; -$btn-padding-x-lg: 1rem; -$btn-font-size-lg: $font-size-lg; // 16px + // Spacing scale - maintain existing spacing + $spacer: 1rem, + $spacers: ( + 0: 0, + 1: 0.25rem, + 2: 0.5rem, + 3: 0.75rem, + 4: 1rem, + 5: 1.5rem, + 6: 7.5rem, + ), -// Form controls -$input-padding-y: 0.375rem; -$input-padding-x: 0.75rem; -$input-font-size: $font-size-base; -$input-line-height: 1.5; + // Buttons - maintain original sizing + $btn-padding-y: 0.375rem, + $btn-padding-x: 0.75rem, + $btn-font-size: 1rem, + $btn-line-height: 1.5, + $btn-padding-y-sm: 0.25rem, + $btn-padding-x-sm: 0.5rem, + $btn-font-size-sm: 0.875rem, + $btn-padding-y-lg: 0.5rem, + $btn-padding-x-lg: 1rem, + $btn-font-size-lg: 1.25rem, -$input-padding-y-sm: 0.25rem; -$input-padding-x-sm: 0.5rem; -$input-font-size-sm: $font-size-sm; // 12px + // Form controls + $input-padding-y: 0.375rem, + $input-padding-x: 0.75rem, + $input-font-size: 1rem, + $input-line-height: 1.5, + $input-padding-y-sm: 0.25rem, + $input-padding-x-sm: 0.5rem, + $input-font-size-sm: 0.875rem, -// Links -$link-color: #337ab7; // Treeherder link color from treeherder-base.css -$link-decoration: none; -$link-hover-decoration: none; + // Links + $link-color: #337ab7, + $link-decoration: none, + $link-hover-decoration: none, -// Navbar -$navbar-dark-color: rgba(255, 255, 255, 0.75); -$navbar-dark-hover-color: rgba(255, 255, 255, 0.9); -$navbar-dark-active-color: #fff; -$navbar-padding-y: 0; -$navbar-padding-x: 0; + // Navbar + $navbar-dark-color: rgba(255, 255, 255, 0.75), + $navbar-dark-hover-color: rgba(255, 255, 255, 0.9), + $navbar-dark-active-color: #fff, + $navbar-padding-y: 0, + $navbar-padding-x: 0, -// Dropdowns -$dropdown-font-size: $font-size-base; -$dropdown-item-padding-y: 0.5rem; -$dropdown-item-padding-x: 1rem; - -// Import Bootstrap 5 with customizations -@import '~bootstrap/scss/bootstrap'; + // Dropdowns + $dropdown-font-size: 1rem, + $dropdown-item-padding-y: 0.5rem, + $dropdown-item-padding-x: 1rem +); diff --git a/ui/intermittent-failures/App.jsx b/ui/intermittent-failures/App.jsx index 432c7e34392..08f4db4a548 100644 --- a/ui/intermittent-failures/App.jsx +++ b/ui/intermittent-failures/App.jsx @@ -1,7 +1,6 @@ import React from 'react'; import { Route, Switch, Redirect } from 'react-router-dom'; import { Container } from 'react-bootstrap'; -import { hot } from 'react-hot-loader/root'; import ErrorMessages from '../shared/ErrorMessages'; @@ -107,4 +106,4 @@ class IntermittentFailuresApp extends React.Component { } } -export default hot(IntermittentFailuresApp); +export default IntermittentFailuresApp; diff --git a/ui/intermittent-failures/BugDetailsView.jsx b/ui/intermittent-failures/BugDetailsView.jsx index fada7ef2b71..1d3c0a9ee3d 100644 --- a/ui/intermittent-failures/BugDetailsView.jsx +++ b/ui/intermittent-failures/BugDetailsView.jsx @@ -3,7 +3,7 @@ import { Row, Col, Breadcrumb, BreadcrumbItem } from 'react-bootstrap'; import { Link } from 'react-router-dom'; import ReactTable from 'react-table-6'; import PropTypes from 'prop-types'; -import { Helmet } from 'react-helmet'; +import { Helmet } from 'react-helmet-async'; import { bugDetailsEndpoint, diff --git a/ui/job-view/App.jsx b/ui/job-view/App.jsx index e9ed89084e1..8091d89989f 100644 --- a/ui/job-view/App.jsx +++ b/ui/job-view/App.jsx @@ -1,6 +1,5 @@ import React from 'react'; import { Modal } from 'react-bootstrap'; -import { hot } from 'react-hot-loader/root'; import SplitPane from 'react-split-pane'; import pick from 'lodash/pick'; import isEqual from 'lodash/isEqual'; @@ -532,4 +531,4 @@ export default connect(mapStateToProps, { pushRoute, clearExpiredNotifications, fetchPushes, -})(hot(App)); +})(App); diff --git a/ui/login-callback/LoginCallback.jsx b/ui/login-callback/LoginCallback.jsx index f7e02b394e4..cabf909e832 100644 --- a/ui/login-callback/LoginCallback.jsx +++ b/ui/login-callback/LoginCallback.jsx @@ -1,5 +1,4 @@ import React from 'react'; -import { hot } from 'react-hot-loader/root'; import moment from 'moment'; import AuthService from '../shared/auth/AuthService'; @@ -82,4 +81,4 @@ class LoginCallback extends React.PureComponent { } } -export default hot(LoginCallback); +export default LoginCallback; diff --git a/ui/logviewer/App.jsx b/ui/logviewer/App.jsx index 9b6090047af..2e19971f141 100644 --- a/ui/logviewer/App.jsx +++ b/ui/logviewer/App.jsx @@ -1,5 +1,4 @@ import React from 'react'; -import { hot } from 'react-hot-loader/root'; import { LazyLog } from 'react-lazylog'; import isEqual from 'lodash/isEqual'; @@ -477,4 +476,4 @@ class App extends React.PureComponent { } } -export default hot(App); +export default App; diff --git a/ui/perfherder/App.jsx b/ui/perfherder/App.jsx index e3bc98f7f23..e92ac76455f 100644 --- a/ui/perfherder/App.jsx +++ b/ui/perfherder/App.jsx @@ -1,6 +1,5 @@ import React from 'react'; import { Route, Switch, Redirect } from 'react-router-dom'; -import { hot } from 'react-hot-loader/root'; import { Container } from 'react-bootstrap'; import { getData, processResponse } from '../helpers/http'; @@ -144,4 +143,4 @@ class App extends React.Component { } } -export default hot(App); +export default App; diff --git a/ui/push-health/App.jsx b/ui/push-health/App.jsx index e8035d3176b..04f44b57f58 100644 --- a/ui/push-health/App.jsx +++ b/ui/push-health/App.jsx @@ -1,5 +1,4 @@ import React from 'react'; -import { hot } from 'react-hot-loader/root'; import { Route, Switch } from 'react-router-dom'; import { @@ -119,4 +118,4 @@ class App extends React.Component { } } -export default hot(App); +export default App; diff --git a/ui/push-health/Health.jsx b/ui/push-health/Health.jsx index 03ba7b0701a..edbb0608e30 100644 --- a/ui/push-health/Health.jsx +++ b/ui/push-health/Health.jsx @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import { Container, Spinner, Navbar, Nav, Alert } from 'react-bootstrap'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import camelCase from 'lodash/camelCase'; -import { Helmet } from 'react-helmet'; +import { Helmet } from 'react-helmet-async'; import { Tab, TabList, TabPanel, Tabs } from 'react-tabs'; import faviconBroken from '../img/push-health-broken.png'; diff --git a/ui/push-health/MyPushes.jsx b/ui/push-health/MyPushes.jsx index 65bafaba303..955e9a2dba4 100644 --- a/ui/push-health/MyPushes.jsx +++ b/ui/push-health/MyPushes.jsx @@ -7,7 +7,7 @@ import { Navbar, Nav, } from 'react-bootstrap'; -import { Helmet } from 'react-helmet'; +import { Helmet } from 'react-helmet-async'; import faviconBroken from '../img/push-health-broken.png'; import faviconOk from '../img/push-health-ok.png'; diff --git a/ui/shared/ComparePageTitle.jsx b/ui/shared/ComparePageTitle.jsx index 6d4dfc7cb46..7fcf57eed0a 100644 --- a/ui/shared/ComparePageTitle.jsx +++ b/ui/shared/ComparePageTitle.jsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Helmet } from 'react-helmet'; +import { Helmet } from 'react-helmet-async'; import PropTypes from 'prop-types'; import { Button, Form, InputGroup } from 'react-bootstrap'; import { faEdit } from '@fortawesome/free-solid-svg-icons'; diff --git a/ui/userguide/App.jsx b/ui/userguide/App.jsx index cfa73a8d7b7..fc95ea6dd3d 100644 --- a/ui/userguide/App.jsx +++ b/ui/userguide/App.jsx @@ -1,5 +1,4 @@ import React from 'react'; -import { hot } from 'react-hot-loader/root'; import PerfherderUserGuide from '../perfherder/userguide/PerherderUserGuide'; @@ -24,4 +23,4 @@ const App = () => ( ); -export default hot(App); +export default App; diff --git a/webpack.config.js b/webpack.config.js index 9e9df07b928..4caa8760945 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -3,7 +3,7 @@ const path = require('path'); const webpack = require('webpack'); const { merge } = require('webpack-merge'); const HtmlWebpackPlugin = require('html-webpack-plugin'); -const HotModuleReplacementPlugin = require('html-webpack-plugin'); +const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin'); const CopyWebpackPlugin = require('copy-webpack-plugin'); const { ProvidePlugin } = require('webpack'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); @@ -185,11 +185,12 @@ const developmentConfig = { }, plugins: [ - new HotModuleReplacementPlugin({ + new HtmlWebpackPlugin({ template: 'ui/index.html', lang: 'en', filename: 'index.html', }), + new ReactRefreshWebpackPlugin(), ], infrastructureLogging: { diff --git a/yarn.lock b/yarn.lock index 993b6228a53..e3c2eefe877 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1799,6 +1799,18 @@ resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== +"@pmmmwh/react-refresh-webpack-plugin@0.6.1": + version "0.6.1" + resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.6.1.tgz#7bb69e155a66f2fa526a7fac1913dc0e5597919f" + integrity sha512-95DXXJxNkpYu+sqmpDp7vbw9JCyiNpHuCsvuMuOgVFrKQlwEIn9Y1+NNIQJq+zFL+eWyxw6htthB5CtdwJupNA== + dependencies: + anser "^2.1.1" + core-js-pure "^3.23.3" + error-stack-parser "^2.0.6" + html-entities "^2.1.0" + schema-utils "^4.2.0" + source-map "^0.7.3" + "@pollyjs/adapter-fetch@6.0.7": version "6.0.7" resolved "https://registry.yarnpkg.com/@pollyjs/adapter-fetch/-/adapter-fetch-6.0.7.tgz#563b5794ae3d958be61acc3f0976c128a58af117" @@ -2795,6 +2807,11 @@ ajv@^6.12.4, ajv@^6.12.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +anser@^2.1.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/anser/-/anser-2.3.2.tgz#e2da9d10759a4243a5819595f4f46ec369970c5b" + integrity sha512-PMqBCBvrOVDRqLGooQb+z+t1Q0PiPyurUQeZRR5uHBOVZcW8B04KMmnT12USnhpNX2wCPagWzLVppQMUG3u0Dw== + ansi-escapes@^4.2.1: version "4.3.2" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" @@ -3244,11 +3261,6 @@ batch@0.6.1: resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== -big.js@^5.2.2: - version "5.2.2" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" - integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== - binary-extensions@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" @@ -3836,6 +3848,11 @@ core-js-compat@^3.40.0: dependencies: browserslist "^4.24.4" +core-js-pure@^3.23.3: + version "3.45.1" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.45.1.tgz#b129d86a5f7f8380378577c7eaee83608570a05a" + integrity sha512-OHnWFKgTUshEU8MK+lOs1H8kC8GkTi9Z1tvNkxrCcw9wl3MJIO7q2ld77wjWn4/xuGrVu2X+nME1iIIPBSdyEQ== + core-js@^2.4.0: version "2.6.12" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" @@ -3887,7 +3904,7 @@ create-ecdh@^4.0.4: bn.js "^4.1.0" elliptic "^6.5.3" -create-hash@^1.1.0, create-hash@^1.2.0: +create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== @@ -3898,7 +3915,7 @@ create-hash@^1.1.0, create-hash@^1.2.0: ripemd160 "^2.0.1" sha.js "^2.4.0" -create-hmac@^1.1.7: +create-hmac@^1.1.4, create-hmac@^1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== @@ -4427,11 +4444,6 @@ dom-serializer@^1.0.1: domhandler "^4.2.0" entities "^2.0.0" -dom-walk@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" - integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== - domelementtype@^2.0.1, domelementtype@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" @@ -4527,11 +4539,6 @@ emoji-regex@^9.2.2: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== -emojis-list@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" - integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== - encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" @@ -4597,6 +4604,13 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" +error-stack-parser@^2.0.6: + version "2.1.4" + resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.1.4.tgz#229cb01cdbfa84440bfa91876285b94680188286" + integrity sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ== + dependencies: + stackframe "^1.3.4" + es-abstract@^1.17.5, es-abstract@^1.23.2, es-abstract@^1.23.3, es-abstract@^1.23.5, es-abstract@^1.23.6, es-abstract@^1.23.9: version "1.23.9" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.23.9.tgz#5b45994b7de78dada5c1bebf1379646b32b9d606" @@ -5608,14 +5622,6 @@ global-prefix@^0.1.4: is-windows "^0.2.0" which "^1.2.12" -global@^4.3.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" - integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w== - dependencies: - min-document "^2.19.0" - process "^0.11.10" - globals@16.1.0: version "16.1.0" resolved "https://registry.yarnpkg.com/globals/-/globals-16.1.0.tgz#ee6ab147d41c64e9f2beaaaf66572d18df8e1e60" @@ -5715,16 +5721,6 @@ hash-base@^3.0.0: readable-stream "^3.6.0" safe-buffer "^5.2.0" -hash-base@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.2.tgz#79d72def7611c3f6e3c3b5730652638001b10a74" - integrity sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg== - dependencies: - inherits "^2.0.4" - readable-stream "^2.3.8" - safe-buffer "^5.2.1" - to-buffer "^1.2.1" - hash-base@~3.0, hash-base@~3.0.4: version "3.0.5" resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.5.tgz#52480e285395cf7fba17dc4c9e47acdc7f248a8a" @@ -5830,6 +5826,11 @@ html-encoding-sniffer@^3.0.0: dependencies: whatwg-encoding "^2.0.0" +html-entities@^2.1.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.6.0.tgz#7c64f1ea3b36818ccae3d3fb48b6974208e984f8" + integrity sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ== + html-escaper@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" @@ -7132,7 +7133,7 @@ json5@^1.0.2: dependencies: minimist "^1.2.0" -json5@^2.1.2, json5@^2.2.3: +json5@^2.2.3: version "2.2.3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== @@ -7240,15 +7241,6 @@ loader-runner@^4.2.0: resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== -loader-utils@^2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" - integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== - dependencies: - big.js "^5.2.2" - emojis-list "^3.0.0" - json5 "^2.1.2" - locate-path@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" @@ -7568,13 +7560,6 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -min-document@^2.19.0: - version "2.19.2" - resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.2.tgz#f95db44639eaae3ac8ea85ae6809ae85ff7e3b81" - integrity sha512-8S5I8db/uZN8r9HSLFVWPdJCvYOejMcEC82VIzNUc6Zkklf/d1gg2psfE79/vyhWOj4+J8MtwmoOz3TmvaGu5A== - dependencies: - dom-walk "^0.1.0" - min-indent@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" @@ -8309,16 +8294,15 @@ path@0.12.7: util "^0.10.3" pbkdf2@^3.1.2: - version "3.1.5" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.5.tgz#444a59d7a259a95536c56e80c89de31cc01ed366" - integrity sha512-Q3CG/cYvCO1ye4QKkuH7EXxs3VC/rI1/trd+qX2+PolbaKG0H+bgcZzrTt96mMyRtejk+JMCiLUn3y29W8qmFQ== + version "3.1.2" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" + integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== dependencies: - create-hash "^1.2.0" - create-hmac "^1.1.7" - ripemd160 "^2.0.3" - safe-buffer "^5.2.1" - sha.js "^2.4.12" - to-buffer "^1.2.1" + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" pend@~1.2.0: version "1.2.0" @@ -8513,7 +8497,7 @@ process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== -process@^0.11.1, process@^0.11.10: +process@^0.11.1: version "0.11.10" resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== @@ -8797,20 +8781,19 @@ react-dom@18.3.1: loose-envify "^1.1.0" scheduler "^0.23.2" -react-fast-compare@^3.1.1, react-fast-compare@^3.2.0: +react-fast-compare@^3.2.0, react-fast-compare@^3.2.2: version "3.2.2" resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz#929a97a532304ce9fee4bcae44234f1ce2c21d49" integrity sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ== -react-helmet@6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/react-helmet/-/react-helmet-6.1.0.tgz#a750d5165cb13cf213e44747502652e794468726" - integrity sha512-4uMzEY9nlDlgxr61NL3XbKRy1hEkXmKNXhjbAIOVw5vcFrsdYbH2FEwcNyWvWinl103nXgzYNlns9ca+8kFiWw== +react-helmet-async@2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/react-helmet-async/-/react-helmet-async-2.0.5.tgz#cfc70cd7bb32df7883a8ed55502a1513747223ec" + integrity sha512-rYUYHeus+i27MvFE+Jaa4WsyBKGkL6qVgbJvSBoX8mbsWoABJXdEO0bZyi0F6i+4f0NuIb8AvqPMj3iXFHkMwg== dependencies: - object-assign "^4.1.1" - prop-types "^15.7.2" - react-fast-compare "^3.1.1" - react-side-effect "^2.1.0" + invariant "^2.2.4" + react-fast-compare "^3.2.2" + shallowequal "^1.1.0" react-highlight-words@0.20.0: version "0.20.0" @@ -8829,20 +8812,6 @@ react-hot-keys@2.7.3: hotkeys-js "^3.13.2" prop-types "^15.8.1" -react-hot-loader@4.13.1: - version "4.13.1" - resolved "https://registry.yarnpkg.com/react-hot-loader/-/react-hot-loader-4.13.1.tgz#979fd7598e27338b3faffae6ed01c65374dace5e" - integrity sha512-ZlqCfVRqDJmMXTulUGic4lN7Ic1SXgHAFw7y/Jb7t25GBgTR0fYAJ8uY4mrpxjRyWGWmqw77qJQGnYbzCvBU7g== - dependencies: - fast-levenshtein "^2.0.6" - global "^4.3.0" - hoist-non-react-statics "^3.3.0" - loader-utils "^2.0.3" - prop-types "^15.6.1" - react-lifecycles-compat "^3.0.4" - shallowequal "^1.1.0" - source-map "^0.7.3" - react-is@^16.13.1, react-is@^16.3.2, react-is@^16.6.0, react-is@^16.7.0: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" @@ -8929,6 +8898,11 @@ react-redux@8.0.7: react-is "^18.0.0" use-sync-external-store "^1.0.0" +react-refresh@0.17.0: + version "0.17.0" + resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.17.0.tgz#b7e579c3657f23d04eccbe4ad2e58a8ed51e7e53" + integrity sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ== + react-router-dom@5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.1.2.tgz#06701b834352f44d37fbb6311f870f84c76b9c18" @@ -8958,11 +8932,6 @@ react-router@5.1.2: tiny-invariant "^1.0.2" tiny-warning "^1.0.0" -react-side-effect@^2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/react-side-effect/-/react-side-effect-2.1.2.tgz#dc6345b9e8f9906dc2eeb68700b615e0b4fe752a" - integrity sha512-PVjOcvVOyIILrYoyGEpDN3vmYNLdy1CajSFNt4TDsVQC5KpTijDvWVoR+/7Rz2xT978D8/ZtFceXxzsPwZEDvw== - react-split-pane@0.1.92: version "0.1.92" resolved "https://registry.yarnpkg.com/react-split-pane/-/react-split-pane-0.1.92.tgz#68242f72138aed95dd5910eeb9d99822c4fc3a41" @@ -9360,14 +9329,6 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^3.0.0" inherits "^2.0.1" -ripemd160@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.3.tgz#9be54e4ba5e3559c8eee06a25cd7648bbccdf5a8" - integrity sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA== - dependencies: - hash-base "^3.1.2" - inherits "^2.0.4" - route-recognizer@^0.3.4: version "0.3.4" resolved "https://registry.yarnpkg.com/route-recognizer/-/route-recognizer-0.3.4.tgz#39ab1ffbce1c59e6d2bdca416f0932611e4f3ca3" @@ -9624,7 +9585,7 @@ setup-polly-jest@0.11.0: resolved "https://registry.yarnpkg.com/setup-polly-jest/-/setup-polly-jest-0.11.0.tgz#2133919099dff9d4f24cfae5945667e16bed7432" integrity sha512-3ywsCFGfCvfi3ZpwYyDc4YDPNiB70QtjODoKFD5hbhza1GMOh0ZzAYUZO9OBmo/1isasynxcS5WzKYMyDJUeZw== -sha.js@^2.4.0, sha.js@^2.4.12, sha.js@^2.4.8: +sha.js@^2.4.0, sha.js@^2.4.8: version "2.4.12" resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.12.tgz#eb8b568bf383dfd1867a32c3f2b74eb52bdbf23f" integrity sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w== @@ -9839,9 +9800,9 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== source-map@^0.7.3: - version "0.7.4" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" - integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== + version "0.7.6" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.6.tgz#a3658ab87e5b6429c8a1f3ba0083d4c61ca3ef02" + integrity sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ== spawnd@^11.0.0: version "11.0.0" @@ -9903,6 +9864,11 @@ stack-utils@^2.0.3: dependencies: escape-string-regexp "^2.0.0" +stackframe@^1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.3.4.tgz#b881a004c8c149a5e8efef37d51b16e412943310" + integrity sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw== + statuses@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" @@ -10207,9 +10173,9 @@ tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0, tapable@^2.2.1: integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== tar-fs@^3.0.8: - version "3.1.1" - resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-3.1.1.tgz#4f164e59fb60f103d472360731e8c6bb4a7fe9ef" - integrity sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg== + version "3.0.9" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-3.0.9.tgz#d570793c6370d7078926c41fa422891566a0b617" + integrity sha512-XF4w9Xp+ZQgifKakjZYmFdkLoSWd34VGKcsTCwlNWM7QG3ZbaxnTsaBwnjFZqHRf/rROxaR8rXnbtwdvaDI+lA== dependencies: pump "^3.0.0" tar-stream "^3.1.5" @@ -10354,15 +10320,6 @@ to-buffer@^1.2.0: safe-buffer "^5.2.1" typed-array-buffer "^1.0.3" -to-buffer@^1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.2.2.tgz#ffe59ef7522ada0a2d1cb5dfe03bb8abc3cdc133" - integrity sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw== - dependencies: - isarray "^2.0.5" - safe-buffer "^5.2.1" - typed-array-buffer "^1.0.3" - to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"