Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/CHANGELOG.md
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/CHANGELOG.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/CHANGELOG.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,328 @@
+## 0.5.16 (31 Mar 2025)
+
+### Fixes
+
+- Fixed out of order cleanup when using top-level await (#898)
+
+## 0.5.15 (3 Jun 2024)
+
+### Fixes
+
+- Fixed wrong import in error overlay for `ansi-html` (#853)
+
+## 0.5.14 (1 Jun 2024)
+
+### Fixes
+
+- Moved to `ansi-html` `v0.0.9` and `schema-utils` `v4.x` (#848)
+
+### Internal
+
+- Run tests on latest versions of Node.js 18, 20 and 22 (#848)
+- Bumped `jest` to v29 and some other development dependencies (#848)
+- Removed `yalc` (#849)
+
+## 0.5.13 (28 Apr 2024)
+
+### Fixes
+
+- Fixed module system inferring (ESM vs CJS) to start from the point of each file (#771)
+
+## 0.5.12 (27 Apr 2024)
+
+### Fixes
+
+- Fixed incorrect `sockProtocol` override (#835)
+- Relaxed peer dependency requirement on `webpack-dev-server` to allow v5.x (#837)
+
+## 0.5.11 (15 Aug 2023)
+
+### Features
+
+- Added support to exclude dynamically generated modules from other loaders (#769)
+
+### Fixes
+
+- Fixed unnecessary memory leaks due to `prevExports` (#766)
+- Relaxed peer dependency requirement on `type-fest` to allow v4.x (#767)
+- Fixed module type resolution when there is difference across contexts (#768)
+
+## 0.5.10 (24 Nov 2022)
+
+### Fixes
+
+- Bumped `loader-utils` to fix security vulnerability (#700)
+
+## 0.5.9 (10 Nov 2022)
+
+### Fixes
+
+- Bumped `loader-utils` to fix security vulnerability (#685)
+
+## 0.5.8 (9 Oct 2022)
+
+### Fixes
+
+- Fixed performance issue regarding `require.resolve` in loader injection (#669)
+- Bumped `core-js-pure` to not depend on deprecated versions (#674)
+
+## 0.5.7 (23 May 2022)
+
+### Fixes
+
+- Removed debug `console.log` statement (#631)
+
+### Internal
+
+- Run tests on Node.js 18 (#631)
+
+## 0.5.6 (10 May 2022)
+
+### Fixes
+
+- Fixed faulty `this` type import in loader (#624)
+- Made current script detection more robust for edge cases (#630)
+
+### Internal
+
+- Swapped to new `ReactDOM.createRoot` API in examples (#626)
+
+## 0.5.5 (4 April 2022)
+
+### Fixes
+
+- Handle unknown `moduleId` for dynamically generated modules (#547)
+- Handle WDS `auto` value on `port` (#574)
+- Fixed `react-refresh@0.12.0` compatibility (#576)
+- Fixed crash when parsing compile errors in overlay (#577)
+- Respect virtual modules when injecting loader (#593)
+- Allow `port` to be missing for WDS, also some general refactoring (#623)
+
+### Internal
+
+- A couple documentation changes in README (#575, 8c39623, #597)
+- Bumped dependencies for testing infrastructure (#526, #564, #567, #581, #588, #591, #594, #616)
+
+## 0.5.4 (22 December 2021)
+
+### Fixes
+
+- Skip loader injection for files referenced as assets (#545)
+- Changed failures of `exports` capturing to warn instead of throw (#546)
+
+## 0.5.3 (28 November 2021)
+
+### Fixes
+
+- Updated overlay for unsafe area in Safari (#528)
+- Fixed performance in large projects due to memory leak in loader (#537)
+
+## 0.5.2 (19 November 2021)
+
+### Features
+
+- Added support for WDS v4 `client.webSocketURL` (#529)
+
+### Fixes
+
+- Fixed lost module context due to interceptor by always using regular functions (#531)
+- Relaxed peer dependency requirement on `react-refresh` (#534)
+
+## 0.5.1 (15 September 2021)
+
+### Fixes
+
+- Relaxed peer dependency requirement on `type-fest` to allow v2.x (#507, #508)
+
+### Internal
+
+- Fixed typos in README (#509)
+
+## 0.5.0 (14 September 2021)
+
+### BREAKING
+
+- While most of the public API did not change,
+  we've re-written a large chunk of the runtime code to support a wider range of use cases.
+  This is likely to provide more stability, but if `0.4.x` works in your setup but `0.5.x` doesn't,
+  please file us an issue - we would love to address it!
+- The `disableRefreshCheck` option have been removed (#285).
+  It has long been effect-less and deprecated since `0.3.x`.
+- The `overlay.useLegacyWDSSockets` have been removed (#498).
+  It is aimed to support WDS below `3.6.0` (published in June 2019),
+  but looking at current usage and download stats,
+  we've decided it is best to drop support for the old socket format moving forward.
+- Handling of port `0` have been removed (#337).
+- `html-entities` have been bumped to `2.x` (#321).
+- `react-refresh` have been bumped to `0.10.0` (#353).
+
+### Features
+
+- Added WDS v4 support with new socket defaults through Webpack config (#241, #286, #392, #413, #479)
+- Added the `overlay.sockProtocol` option (#242)
+- Added monorepo compatibility via the the `library` option (#273)
+- Rewritten URL handling using WHATWG `URL` APIs with automatic pony-filling (#278, #332, #378)
+- Rewritten Webpack 5 compatibility using new APIs and hooks (#319, #372, #434, #483)
+- Rewritten refresh runtime to be fully module system aware (#337, #461, #482, #492)
+- Rewritten Webpack 4 and 5 checks using feature detection on compiler (#415)
+- Added support for `experiments.topLevelAwait` (#435, #447, #493)
+- Added retry logic when socket initialisation fails (#446)
+
+### Fixes
+
+- Relaxed peer dependency requirement on `type-fest` (#257, c02018a, #484)
+- Relaxed requirement on the `overlay` option to accept relative paths (#284)
+- Patched unstable initialisation of global scope across module boundaries (#290, #369, #464, #505)
+- Patched quote escaping in injected runtime code (#306)
+- Invalidate updates outside of Refresh boundary for consistency (#307)
+- Properly throw when an ambiguous entrypoint is received while using Webpack 4 (#320)
+- Fixed overlay script source detection for WDS when no `src` is found (#331)
+- Fixed possible Stack Overflow through self-referencing (#370, #380)
+- Relaxed errors on HMR not found to not crash JS parsing (#371)
+- Ensure overlay code won't run if disabled (#374)
+- Relaxed peer dependency requirement on `@types/webpack` (#414)
+- Fixed compiler error overlay crashes when messages are empty (#462)
+- Swapped `ansi-html` to `ansi-html-community` to fix ReDoS vulnerability (#501)
+
+### Internal
+
+- More stable testing infrastructure (#234)
+- Run tests by default on Webpack 5 (#440)
+- Rewrite documentation and fix outstanding issues (#283, #291, #311, #376, #480, #497, #499)
+- Added documentation on community plugins: `react-refresh-typescript` and `swc` (#248, fbe1f27, #450)
+
+## 0.4.3 (2 November 2020)
+
+### Fixes
+
+- Fixed Yarn 2 PnP compatibility with absolute `react-refresh/runtime` imports (#230)
+- Fixed Webpack 5 compatibility by requiring `__webpack_require__` (#233)
+- Fixed IE 11 compatibility in socket code (4033e6af)
+- Relaxed peer dependency requirement for `react-refresh` to allow `0.9.x` (747c19ba)
+
+## 0.4.2 (3 September 2020)
+
+### Fixes
+
+- Patched loader to use with Node.js global `fetch` polyfills (#193)
+- Patched default `include` and `exclude` options to be case-insensitive (#194)
+
+## 0.4.1 (28 July 2020)
+
+### Fixes
+
+- Fixed accidental use of testing alias `webpack.next` in published plugin code (#167)
+
+## 0.4.0 (28 July 2020)
+
+### BREAKING
+
+- Minimum required Node.js version have been bumped to 10 as Node.js 8 is EOL now.
+- Minimum required Webpack version is now `v4.43.0` or later as we adopted the new `module.hot.invalidate` API (#89).
+  The new API enabled us to bail out of the HMR loop less frequently and provide a better experience.
+  If you really cannot upgrade, you can stay on `0.3.3` for the time being.
+- While most of our public API did not change, this release is closer to a rewrite than a refactor.
+  A lot of files have moved to provide easier access for advanced users and frameworks (#122).
+  You can check the difference in the PR to see what have moved and where they are now.
+- The `useLegacyWDSSockets` option is now scoped under the `overlay` option (#153).
+
+### Features
+
+- Adopted the `module.hot.invalidate()` API, which means we will now bail out less often (#89)
+- Attach runtime on Webpack's global scope instead of `window`, making the plugin platform-agnostic (#102)
+- Added stable support for **Webpack 5** and beta support for **Module Federation** (#123, #132, #164)
+- Socket integration URL detection via `document.currentScript` (#133)
+- Relaxed requirements for "required" `overlay` options to receive `false` as value (#154)
+- Prefixed all errors thrown by the plugin (#161)
+- Eliminated use of soon-to-be-deprecated `lodash.debounce` package (#163)
+
+### Fixes
+
+- Fixed circular references for `__react_refresh_error_overlay__` and `__react_refresh_utils` (#116)
+- Fixed IE11 compatibility (#106, #121)
+- Rearranged directories to provide more ergonomic imports (#122)
+- Fixed issues with Babel/ESLint/Flow regarding loader ordering and runtime cleanup (#129, #140)
+- Correctly detecting the HMR plugin (#130, #160)
+- Fixed unwanted injection of error overlay in non-browser environment (#146)
+- Scoped the `useLegacyWDSSockets` options under `overlay` to reflect its true use (#153)
+- Fixed non-preserved relative ordering of Webpack entries (#165)
+
+### Internal
+
+- Full HMR test suite - we are confident the plugin works! (#93, #96)
+- Unit tests for all plugin-related Node.js code (#127)
+
+## 0.3.3 (29 May 2020)
+
+### Fixes
+
+- Removed unrecoverable React errors check and its corresponding bail out logic on hot dispose (#104)
+
+## 0.3.2 (22 May 2020)
+
+### Fixes
+
+- Fixed error in overlay when stack trace is unavailable (#91)
+- Fixed IE11 compatibility (#98)
+
+## 0.3.1 (11 May 2020)
+
+### Fixes
+
+- Relaxed peer dependency requirements for `webpack-plugin-serve`
+
+## 0.3.0 (10 May 2020)
+
+### BREAKING
+
+- Deprecated the `disableRefreshCheck` flag (#60)
+
+### Features
+
+- Added custom error overlay support (#44)
+- Added example project to use TypeScript without usual Babel settings (#46)
+- Added custom socket parameters for WDS (#52)
+- Added TypeScript definition files (#65)
+- Added stricter options validation rules (#62)
+- Added option to configure socket runtime to support more hot integrations (#64)
+- Added support for `webpack-plugin-serve` (#74)
+
+### Fixes
+
+- Fixed non-dismissible overlay for build warnings (#57)
+- Fixed electron compatibility (#58)
+- Fixed optional peer dependencies to be truly optional (#59)
+- Fixed compatibility issues caused by `node-url` (#61)
+- Removed check for `react` import for compatibility (#69)
+
+## 0.2.0 (2 March 2020)
+
+### Features
+
+- Added `webpack-hot-middleware` support (#23)
+
+### Fixes
+
+- Fixed dependency on a global `this` variable to better support web workers (#29)
+
+## 0.1.3 (19 December 2019)
+
+### Fixes
+
+- Fixed runtime template injection when the `runtimeChunks` optimization is used in Webpack (#26)
+
+## 0.1.2 (18 December 2019)
+
+### Fixes
+
+- Fixed caching of Webpack loader to significantly improve performance (#22)
+
+## 0.1.1 (13 December 2019)
+
+### Fixes
+
+- Fixed usage of WDS SockJS fallback (#17)
+
+## 0.1.0 (7 December 2019)
+
+- Initial public release
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/LICENSE
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/LICENSE	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/LICENSE	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019 Michael Mok
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/README.md
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/README.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/README.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,348 @@
+# React Refresh Webpack Plugin
+
+[actions]: https://github.com/pmmmwh/react-refresh-webpack-plugin/actions/workflows/ci.yml
+[actions:badge]: https://img.shields.io/github/actions/workflow/status/pmmmwh/react-refresh-webpack-plugin/ci.yml?branch=main
+[license:badge]: https://img.shields.io/github/license/pmmmwh/react-refresh-webpack-plugin
+[npm:latest]: https://www.npmjs.com/package/@pmmmwh/react-refresh-webpack-plugin/v/latest
+[npm:latest:badge]: https://img.shields.io/npm/v/@pmmmwh/react-refresh-webpack-plugin/latest
+[npm:next]: https://www.npmjs.com/package/@pmmmwh/react-refresh-webpack-plugin/v/next
+[npm:next:badge]: https://img.shields.io/npm/v/@pmmmwh/react-refresh-webpack-plugin/next
+
+[![GitHub Actions][actions:badge]][actions]
+[![License][license:badge]](./LICENSE)
+[![Latest Version][npm:latest:badge]][npm:latest]
+[![Next Version][npm:next:badge]][npm:next]
+
+An **EXPERIMENTAL** Webpack plugin to enable "Fast Refresh" (also known as _Hot Reloading_) for React components.
+
+> This plugin is not 100% stable.
+> We're hoping to land a v1 release soon - please help us by reporting any issues you've encountered!
+
+## Getting Started
+
+### Prerequisites
+
+Ensure that you are using at least the minimum supported versions of this plugin's peer dependencies -
+older versions unfortunately do not contain code to orchestrate "Fast Refresh",
+and thus cannot be made compatible.
+
+We recommend using the following versions:
+
+| Dependency      | Version                      |
+| --------------- | ---------------------------- |
+| `react`         | `16.13.0`+, `17.x` or `18.x` |
+| `react-dom`     | `16.13.0`+, `17.x` or `18.x` |
+| `react-refresh` | `0.10.0`+                    |
+| `webpack`       | `4.46.0`+ or `5.2.0`+        |
+
+<details>
+<summary>Minimum requirements</summary>
+<br />
+
+| Dependency      | Version  |
+| --------------- | -------- |
+| `react`         | `16.9.0` |
+| `react-dom`     | `16.9.0` |
+| `react-refresh` | `0.10.0` |
+| `webpack`       | `4.43.0` |
+
+</details>
+
+<details>
+<summary>Using custom renderers (e.g. <code>react-three-fiber</code>, <code>react-pdf</code>, <code>ink</code>)</summary>
+<br />
+
+To ensure full support of "Fast Refresh" with components rendered by custom renderers,
+you should ensure the renderer you're using depends on a recent version of `react-reconciler`.
+
+We recommend version `0.25.0` or above, but any versions above `0.22.0` should work.
+
+If the renderer is not compatible, please file them an issue instead.
+
+</details>
+
+### Installation
+
+With all prerequisites met, you can install this plugin using your package manager of choice:
+
+```sh
+# if you prefer npm
+npm install -D @pmmmwh/react-refresh-webpack-plugin react-refresh
+
+# if you prefer yarn
+yarn add -D @pmmmwh/react-refresh-webpack-plugin react-refresh
+
+# if you prefer pnpm
+pnpm add -D @pmmmwh/react-refresh-webpack-plugin react-refresh
+```
+
+The `react-refresh` package (from the React team) is a required peer dependency of this plugin.
+We recommend using version `0.10.0` or above.
+
+<details>
+<summary>Support for TypeScript</summary>
+<br />
+
+TypeScript support is available out-of-the-box for those who use `webpack.config.ts`.
+
+Our exported types however depends on `type-fest`, so you'll have to add it as a `devDependency`:
+
+```sh
+# if you prefer npm
+npm install -D type-fest
+
+# if you prefer yarn
+yarn add -D type-fest
+
+# if you prefer pnpm
+pnpm add -D type-fest
+```
+
+> **:memo: Note**:
+>
+> `type-fest@4.x` only supports Node.js v16 or above,
+> `type-fest@3.x` only supports Node.js v14.16 or above,
+> and `type-fest@2.x` only supports Node.js v12.20 or above.
+> If you're using an older version of Node.js, please install `type-fest@1.x`.
+
+</details>
+
+### Usage
+
+For most setups, we recommend integrating with `babel-loader`.
+It covers the most use cases and is officially supported by the React team.
+
+The example below will assume you're using `webpack-dev-server`.
+
+If you haven't done so, set up your development Webpack configuration for Hot Module Replacement (HMR).
+
+```js
+const isDevelopment = process.env.NODE_ENV !== 'production';
+
+module.exports = {
+  mode: isDevelopment ? 'development' : 'production',
+  devServer: {
+    hot: true,
+  },
+};
+```
+
+<details>
+<summary>Using <code>webpack-hot-middleware</code></summary>
+<br />
+
+```js
+const webpack = require('webpack');
+
+const isDevelopment = process.env.NODE_ENV !== 'production';
+
+module.exports = {
+  mode: isDevelopment ? 'development' : 'production',
+  plugins: [isDevelopment && new webpack.HotModuleReplacementPlugin()].filter(Boolean),
+};
+```
+
+</details>
+
+<details>
+<summary>Using <code>webpack-plugin-serve</code></summary>
+<br />
+
+```js
+const { WebpackPluginServe } = require('webpack-plugin-serve');
+
+const isDevelopment = process.env.NODE_ENV !== 'production';
+
+module.exports = {
+  mode: isDevelopment ? 'development' : 'production',
+  plugins: [isDevelopment && new WebpackPluginServe()].filter(Boolean),
+};
+```
+
+</details>
+
+Then, add the `react-refresh/babel` plugin to your Babel configuration and this plugin to your Webpack configuration.
+
+```js
+const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
+
+const isDevelopment = process.env.NODE_ENV !== 'production';
+
+module.exports = {
+  mode: isDevelopment ? 'development' : 'production',
+  module: {
+    rules: [
+      {
+        test: /\.[jt]sx?$/,
+        exclude: /node_modules/,
+        use: [
+          {
+            loader: require.resolve('babel-loader'),
+            options: {
+              plugins: [isDevelopment && require.resolve('react-refresh/babel')].filter(Boolean),
+            },
+          },
+        ],
+      },
+    ],
+  },
+  plugins: [isDevelopment && new ReactRefreshWebpackPlugin()].filter(Boolean),
+};
+```
+
+> **:memo: Note**:
+>
+> Ensure both the Babel transform (`react-refresh/babel`) and this plugin are enabled only in `development` mode!
+
+<details>
+<summary>Using <code>ts-loader</code></summary>
+<br />
+
+> **:warning: Warning**:
+> This is an un-official integration maintained by the community.
+
+Install [`react-refresh-typescript`](https://github.com/Jack-Works/react-refresh-transformer/tree/main/typescript).
+Ensure your TypeScript version is at least 4.0.
+
+```sh
+# if you prefer npm
+npm install -D react-refresh-typescript
+
+# if you prefer yarn
+yarn add -D react-refresh-typescript
+
+# if you prefer pnpm
+pnpm add -D react-refresh-typescript
+```
+
+Then, instead of wiring up `react-refresh/babel` via `babel-loader`,
+you can wire-up `react-refresh-typescript` with `ts-loader`:
+
+```js
+const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
+const ReactRefreshTypeScript = require('react-refresh-typescript');
+
+const isDevelopment = process.env.NODE_ENV !== 'production';
+
+module.exports = {
+  mode: isDevelopment ? 'development' : 'production',
+  module: {
+    rules: [
+      {
+        test: /\.[jt]sx?$/,
+        exclude: /node_modules/,
+        use: [
+          {
+            loader: require.resolve('ts-loader'),
+            options: {
+              getCustomTransformers: () => ({
+                before: [isDevelopment && ReactRefreshTypeScript()].filter(Boolean),
+              }),
+              transpileOnly: isDevelopment,
+            },
+          },
+        ],
+      },
+    ],
+  },
+  plugins: [isDevelopment && new ReactRefreshWebpackPlugin()].filter(Boolean),
+};
+```
+
+> It is recommended to run `ts-loader` with `transpileOnly` is set to `true`.
+> You can use `ForkTsCheckerWebpackPlugin` as an alternative if you need typechecking during development.
+
+</details>
+
+<details>
+<summary>Using <code>swc-loader</code></summary>
+<br />
+
+> **:warning: Warning**:
+> This is an un-official integration maintained by the community.
+
+Ensure your `@swc/core` version is at least `1.2.86`.
+It is also recommended to use `swc-loader` version `0.1.13` or above.
+
+Then, instead of wiring up `react-refresh/babel` via `babel-loader`,
+you can wire-up `swc-loader` and use the `refresh` transform:
+
+```js
+const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
+
+const isDevelopment = process.env.NODE_ENV !== 'production';
+
+module.exports = {
+  mode: isDevelopment ? 'development' : 'production',
+  module: {
+    rules: [
+      {
+        test: /\.[jt]sx?$/,
+        exclude: /node_modules/,
+        use: [
+          {
+            loader: require.resolve('swc-loader'),
+            options: {
+              jsc: {
+                transform: {
+                  react: {
+                    development: isDevelopment,
+                    refresh: isDevelopment,
+                  },
+                },
+              },
+            },
+          },
+        ],
+      },
+    ],
+  },
+  plugins: [isDevelopment && new ReactRefreshWebpackPlugin()].filter(Boolean),
+};
+```
+
+> Starting from version `0.1.13`, `swc-loader` will set the `development` option based on Webpack's `mode` option.
+> `swc` won't enable fast refresh when `development` is `false`.
+
+</details>
+
+For more information on how to set up "Fast Refresh" with different integrations,
+please check out [our examples](examples).
+
+### Overlay Integration
+
+This plugin integrates with the most common Webpack HMR solutions to surface errors during development -
+in the form of an error overlay.
+
+By default, `webpack-dev-server` is used,
+but you can set the [`overlay.sockIntegration`](docs/API.md#sockintegration) option to match what you're using.
+
+The supported versions are as follows:
+
+| Dependency               | Version                    |
+| ------------------------ | -------------------------- |
+| `webpack-dev-server`     | `3.6.0`+ or `4.x` or `5.x` |
+| `webpack-hot-middleware` | `2.x`                      |
+| `webpack-plugin-serve`   | `0.x` or `1.x`             |
+
+## API
+
+Please refer to [the API docs](docs/API.md) for all available options.
+
+## FAQs and Troubleshooting
+
+Please refer to [the Troubleshooting guide](docs/TROUBLESHOOTING.md) for FAQs and resolutions to common issues.
+
+## License
+
+This project is licensed under the terms of the [MIT License](/LICENSE).
+
+## Special Thanks
+
+<a href="https://jb.gg/OpenSource?from=ReactRefreshWebpackPlugin" target="_blank">
+  <img
+    alt="JetBrains Logo"
+    src="https://user-images.githubusercontent.com/9338255/132110580-61d3dba5-f5c7-4479-bd8e-39cd65b42fc5.png"
+    width="120"
+  />
+</a>
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/client/ErrorOverlayEntry.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/client/ErrorOverlayEntry.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/client/ErrorOverlayEntry.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,100 @@
+/* global __react_refresh_error_overlay__, __react_refresh_socket__, __resourceQuery */
+
+const events = require('./utils/errorEventHandlers.js');
+const formatWebpackErrors = require('./utils/formatWebpackErrors.js');
+const runWithPatchedUrl = require('./utils/patchUrl.js');
+const runWithRetry = require('./utils/retry.js');
+
+// Setup error states
+let isHotReload = false;
+let hasRuntimeErrors = false;
+
+/**
+ * Try dismissing the compile error overlay.
+ * This will also reset runtime error records (if any),
+ * because we have new source to evaluate.
+ * @returns {void}
+ */
+function tryDismissErrorOverlay() {
+  __react_refresh_error_overlay__.clearCompileError();
+  __react_refresh_error_overlay__.clearRuntimeErrors(!hasRuntimeErrors);
+  hasRuntimeErrors = false;
+}
+
+/**
+ * A function called after a compile success signal is received from Webpack.
+ * @returns {void}
+ */
+function handleCompileSuccess() {
+  isHotReload = true;
+
+  if (isHotReload) {
+    tryDismissErrorOverlay();
+  }
+}
+
+/**
+ * A function called after a compile errored signal is received from Webpack.
+ * @param {string[]} errors
+ * @returns {void}
+ */
+function handleCompileErrors(errors) {
+  isHotReload = true;
+
+  const formattedErrors = formatWebpackErrors(errors);
+
+  // Only show the first error
+  __react_refresh_error_overlay__.showCompileError(formattedErrors[0]);
+}
+
+/**
+ * Handles compilation messages from Webpack.
+ * Integrates with a compile error overlay.
+ * @param {*} message A Webpack HMR message sent via WebSockets.
+ * @returns {void}
+ */
+function compileMessageHandler(message) {
+  switch (message.type) {
+    case 'ok':
+    case 'still-ok':
+    case 'warnings': {
+      // TODO: Implement handling for warnings
+      handleCompileSuccess();
+      break;
+    }
+    case 'errors': {
+      handleCompileErrors(message.data);
+      break;
+    }
+    default: {
+      // Do nothing.
+    }
+  }
+}
+
+if (process.env.NODE_ENV !== 'production') {
+  if (typeof window !== 'undefined') {
+    runWithPatchedUrl(function setupOverlay() {
+      // Only register if no other overlay have been registered
+      if (!window.__reactRefreshOverlayInjected && __react_refresh_socket__) {
+        // Registers handlers for compile errors with retry -
+        // This is to prevent mismatching injection order causing errors to be thrown
+        runWithRetry(function initSocket() {
+          __react_refresh_socket__.init(compileMessageHandler, __resourceQuery);
+        }, 3);
+        // Registers handlers for runtime errors
+        events.handleError(function handleError(error) {
+          hasRuntimeErrors = true;
+          __react_refresh_error_overlay__.handleRuntimeError(error);
+        });
+        events.handleUnhandledRejection(function handleUnhandledPromiseRejection(error) {
+          hasRuntimeErrors = true;
+          __react_refresh_error_overlay__.handleRuntimeError(error);
+        });
+
+        // Mark overlay as injected to prevent double-injection
+        window.__reactRefreshOverlayInjected = true;
+      }
+    });
+  }
+}
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/client/ReactRefreshEntry.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/client/ReactRefreshEntry.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/client/ReactRefreshEntry.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,23 @@
+/* global __react_refresh_library__ */
+
+const safeThis = require('core-js-pure/features/global-this');
+const RefreshRuntime = require('react-refresh/runtime');
+
+if (process.env.NODE_ENV !== 'production') {
+  if (typeof safeThis !== 'undefined') {
+    var $RefreshInjected$ = '__reactRefreshInjected';
+    // Namespace the injected flag (if necessary) for monorepo compatibility
+    if (typeof __react_refresh_library__ !== 'undefined' && __react_refresh_library__) {
+      $RefreshInjected$ += '_' + __react_refresh_library__;
+    }
+
+    // Only inject the runtime if it hasn't been injected
+    if (!safeThis[$RefreshInjected$]) {
+      // Inject refresh runtime into global scope
+      RefreshRuntime.injectIntoGlobalHook(safeThis);
+
+      // Mark the runtime as injected to prevent double-injection
+      safeThis[$RefreshInjected$] = true;
+    }
+  }
+}
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/client/package.json
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/client/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/client/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+{
+  "type": "commonjs"
+}
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/client/utils/errorEventHandlers.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/client/utils/errorEventHandlers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/client/utils/errorEventHandlers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,102 @@
+/**
+ * @callback EventCallback
+ * @param {string | Error | null} context
+ * @returns {void}
+ */
+/**
+ * @callback EventHandler
+ * @param {Event} event
+ * @returns {void}
+ */
+
+/**
+ * A function that creates an event handler for the `error` event.
+ * @param {EventCallback} callback A function called to handle the error context.
+ * @returns {EventHandler} A handler for the `error` event.
+ */
+function createErrorHandler(callback) {
+  return function errorHandler(event) {
+    if (!event || !event.error) {
+      return callback(null);
+    }
+    if (event.error instanceof Error) {
+      return callback(event.error);
+    }
+    // A non-error was thrown, we don't have a trace. :(
+    // Look in your browser's devtools for more information
+    return callback(new Error(event.error));
+  };
+}
+
+/**
+ * A function that creates an event handler for the `unhandledrejection` event.
+ * @param {EventCallback} callback A function called to handle the error context.
+ * @returns {EventHandler} A handler for the `unhandledrejection` event.
+ */
+function createRejectionHandler(callback) {
+  return function rejectionHandler(event) {
+    if (!event || !event.reason) {
+      return callback(new Error('Unknown'));
+    }
+    if (event.reason instanceof Error) {
+      return callback(event.reason);
+    }
+    // A non-error was rejected, we don't have a trace :(
+    // Look in your browser's devtools for more information
+    return callback(new Error(event.reason));
+  };
+}
+
+/**
+ * Creates a handler that registers an EventListener on window for a valid type
+ * and calls a callback when the event fires.
+ * @param {string} eventType A valid DOM event type.
+ * @param {function(EventCallback): EventHandler} createHandler A function that creates an event handler.
+ * @returns {register} A function that registers the EventListener given a callback.
+ */
+function createWindowEventHandler(eventType, createHandler) {
+  /**
+   * @type {EventHandler | null} A cached event handler function.
+   */
+  let eventHandler = null;
+
+  /**
+   * Unregisters an EventListener if it has been registered.
+   * @returns {void}
+   */
+  function unregister() {
+    if (eventHandler === null) {
+      return;
+    }
+    window.removeEventListener(eventType, eventHandler);
+    eventHandler = null;
+  }
+
+  /**
+   * Registers an EventListener if it hasn't been registered.
+   * @param {EventCallback} callback A function called after the event handler to handle its context.
+   * @returns {unregister | void} A function to unregister the registered EventListener if registration is performed.
+   */
+  function register(callback) {
+    if (eventHandler !== null) {
+      return;
+    }
+    eventHandler = createHandler(callback);
+    window.addEventListener(eventType, eventHandler);
+
+    return unregister;
+  }
+
+  return register;
+}
+
+const handleError = createWindowEventHandler('error', createErrorHandler);
+const handleUnhandledRejection = createWindowEventHandler(
+  'unhandledrejection',
+  createRejectionHandler
+);
+
+module.exports = {
+  handleError: handleError,
+  handleUnhandledRejection: handleUnhandledRejection,
+};
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/client/utils/formatWebpackErrors.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/client/utils/formatWebpackErrors.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/client/utils/formatWebpackErrors.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,96 @@
+/**
+ * @typedef {Object} WebpackErrorObj
+ * @property {string} moduleIdentifier
+ * @property {string} moduleName
+ * @property {string} message
+ */
+
+const friendlySyntaxErrorLabel = 'Syntax error:';
+
+/**
+ * Checks if the error message is for a syntax error.
+ * @param {string} message The raw Webpack error message.
+ * @returns {boolean} Whether the error message is for a syntax error.
+ */
+function isLikelyASyntaxError(message) {
+  return message.indexOf(friendlySyntaxErrorLabel) !== -1;
+}
+
+/**
+ * Cleans up Webpack error messages.
+ *
+ * This implementation is based on the one from [create-react-app](https://github.com/facebook/create-react-app/blob/edc671eeea6b7d26ac3f1eb2050e50f75cf9ad5d/packages/react-dev-utils/formatWebpackMessages.js).
+ * @param {string} message The raw Webpack error message.
+ * @returns {string} The formatted Webpack error message.
+ */
+function formatMessage(message) {
+  let lines = message.split('\n');
+
+  // Strip Webpack-added headers off errors/warnings
+  // https://github.com/webpack/webpack/blob/master/lib/ModuleError.js
+  lines = lines.filter(function (line) {
+    return !/Module [A-z ]+\(from/.test(line);
+  });
+
+  // Remove leading newline
+  if (lines.length > 2 && lines[1].trim() === '') {
+    lines.splice(1, 1);
+  }
+
+  // Remove duplicated newlines
+  lines = lines.filter(function (line, index, arr) {
+    return index === 0 || line.trim() !== '' || line.trim() !== arr[index - 1].trim();
+  });
+
+  // Clean up the file name
+  lines[0] = lines[0].replace(/^(.*) \d+:\d+-\d+$/, '$1');
+
+  // Cleans up verbose "module not found" messages for files and packages.
+  if (lines[1] && lines[1].indexOf('Module not found: ') === 0) {
+    lines = [
+      lines[0],
+      lines[1]
+        .replace('Error: ', '')
+        .replace('Module not found: Cannot find file:', 'Cannot find file:'),
+    ];
+  }
+
+  message = lines.join('\n');
+
+  // Clean up syntax errors
+  message = message.replace('SyntaxError:', friendlySyntaxErrorLabel);
+
+  // Internal stacks are generally useless, so we strip them -
+  // except the stacks containing `webpack:`,
+  // because they're normally from user code generated by webpack.
+  message = message.replace(/^\s*at\s((?!webpack:).)*:\d+:\d+[\s)]*(\n|$)/gm, ''); // at ... ...:x:y
+  message = message.replace(/^\s*at\s((?!webpack:).)*<anonymous>[\s)]*(\n|$)/gm, ''); // at ... <anonymous>
+  message = message.replace(/^\s*at\s<anonymous>(\n|$)/gm, ''); // at <anonymous>
+
+  return message.trim();
+}
+
+/**
+ * Formats Webpack error messages into a more readable format.
+ * @param {Array<string | WebpackErrorObj>} errors An array of Webpack error messages.
+ * @returns {string[]} The formatted Webpack error messages.
+ */
+function formatWebpackErrors(errors) {
+  let formattedErrors = errors.map(function (errorObjOrMessage) {
+    // Webpack 5 compilation errors are in the form of descriptor objects,
+    // so we have to join pieces to get the format we want.
+    if (typeof errorObjOrMessage === 'object') {
+      return formatMessage([errorObjOrMessage.moduleName, errorObjOrMessage.message].join('\n'));
+    }
+    // Webpack 4 compilation errors are strings
+    return formatMessage(errorObjOrMessage);
+  });
+
+  if (formattedErrors.some(isLikelyASyntaxError)) {
+    // If there are any syntax errors, show just them.
+    formattedErrors = formattedErrors.filter(isLikelyASyntaxError);
+  }
+  return formattedErrors;
+}
+
+module.exports = formatWebpackErrors;
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/client/utils/patchUrl.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/client/utils/patchUrl.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/client/utils/patchUrl.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,40 @@
+/* global __react_refresh_polyfill_url__ */
+
+/**
+ * @typedef {Object} UrlAPIs
+ * @property {typeof URL} URL
+ * @property {typeof URLSearchParams} URLSearchParams
+ */
+
+/**
+ * Runs a callback with patched the DOM URL APIs.
+ * @param {function(UrlAPIs): void} callback The code to run with patched URL globals.
+ * @returns {void}
+ */
+function runWithPatchedUrl(callback) {
+  var __originalURL;
+  var __originalURLSearchParams;
+
+  // Polyfill the DOM URL and URLSearchParams constructors
+  if (__react_refresh_polyfill_url__ || !window.URL) {
+    __originalURL = window.URL;
+    window.URL = require('core-js-pure/web/url');
+  }
+  if (__react_refresh_polyfill_url__ || !window.URLSearchParams) {
+    __originalURLSearchParams = window.URLSearchParams;
+    window.URLSearchParams = require('core-js-pure/web/url-search-params');
+  }
+
+  // Pass in URL APIs in case they are needed
+  callback({ URL: window.URL, URLSearchParams: window.URLSearchParams });
+
+  // Restore polyfill-ed APIs to their original state
+  if (__originalURL) {
+    window.URL = __originalURL;
+  }
+  if (__originalURLSearchParams) {
+    window.URLSearchParams = __originalURLSearchParams;
+  }
+}
+
+module.exports = runWithPatchedUrl;
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/client/utils/retry.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/client/utils/retry.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/client/utils/retry.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,23 @@
+function runWithRetry(callback, maxRetries) {
+  function executeWithRetryAndTimeout(currentCount) {
+    try {
+      if (currentCount > maxRetries - 1) {
+        console.warn('[React Refresh] Failed to set up the socket connection.');
+        return;
+      }
+
+      callback();
+    } catch (err) {
+      setTimeout(
+        function () {
+          executeWithRetryAndTimeout(currentCount + 1);
+        },
+        Math.pow(10, currentCount)
+      );
+    }
+  }
+
+  executeWithRetryAndTimeout(0);
+}
+
+module.exports = runWithRetry;
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/globals.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/globals.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/globals.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,22 @@
+/**
+ * Gets current bundle's global scope identifier for React Refresh.
+ * @param {Record<string, string>} runtimeGlobals The Webpack runtime globals.
+ * @returns {string} The React Refresh global scope within the Webpack bundle.
+ */
+module.exports.getRefreshGlobalScope = (runtimeGlobals) => {
+  return `${runtimeGlobals.require || '__webpack_require__'}.$Refresh$`;
+};
+
+/**
+ * Gets current Webpack version according to features on the compiler instance.
+ * @param {import('webpack').Compiler} compiler The current Webpack compiler instance.
+ * @returns {number} The current Webpack version.
+ */
+module.exports.getWebpackVersion = (compiler) => {
+  if (!compiler.hooks) {
+    throw new Error(`[ReactRefreshPlugin] Webpack version is not supported!`);
+  }
+
+  // Webpack v5+ implements compiler caching
+  return 'cache' in compiler ? 5 : 4;
+};
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/index.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,367 @@
+const { validate: validateOptions } = require('schema-utils');
+const { getRefreshGlobalScope, getWebpackVersion } = require('./globals');
+const {
+  getAdditionalEntries,
+  getIntegrationEntry,
+  getRefreshGlobal,
+  getSocketIntegration,
+  injectRefreshEntry,
+  injectRefreshLoader,
+  makeRefreshRuntimeModule,
+  normalizeOptions,
+} = require('./utils');
+const schema = require('./options.json');
+
+class ReactRefreshPlugin {
+  /**
+   * @param {import('./types').ReactRefreshPluginOptions} [options] Options for react-refresh-plugin.
+   */
+  constructor(options = {}) {
+    validateOptions(schema, options, {
+      name: 'React Refresh Plugin',
+      baseDataPath: 'options',
+    });
+
+    /**
+     * @readonly
+     * @type {import('./types').NormalizedPluginOptions}
+     */
+    this.options = normalizeOptions(options);
+  }
+
+  /**
+   * Applies the plugin.
+   * @param {import('webpack').Compiler} compiler A webpack compiler object.
+   * @returns {void}
+   */
+  apply(compiler) {
+    // Skip processing in non-development mode, but allow manual force-enabling
+    if (
+      // Webpack do not set process.env.NODE_ENV, so we need to check for mode.
+      // Ref: https://github.com/webpack/webpack/issues/7074
+      (compiler.options.mode !== 'development' ||
+        // We also check for production process.env.NODE_ENV,
+        // in case it was set and mode is non-development (e.g. 'none')
+        (process.env.NODE_ENV && process.env.NODE_ENV === 'production')) &&
+      !this.options.forceEnable
+    ) {
+      return;
+    }
+
+    const webpackVersion = getWebpackVersion(compiler);
+    const logger = compiler.getInfrastructureLogger(this.constructor.name);
+
+    // Get Webpack imports from compiler instance (if available) -
+    // this allow mono-repos to use different versions of Webpack without conflicts.
+    const webpack = compiler.webpack || require('webpack');
+    const {
+      DefinePlugin,
+      EntryDependency,
+      EntryPlugin,
+      ModuleFilenameHelpers,
+      NormalModule,
+      ProvidePlugin,
+      RuntimeGlobals,
+      Template,
+    } = webpack;
+
+    // Inject react-refresh context to all Webpack entry points.
+    // This should create `EntryDependency` objects when available,
+    // and fallback to patching the `entry` object for legacy workflows.
+    const addEntries = getAdditionalEntries({
+      devServer: compiler.options.devServer,
+      options: this.options,
+    });
+    if (EntryPlugin) {
+      // Prepended entries does not care about injection order,
+      // so we can utilise EntryPlugin for simpler logic.
+      addEntries.prependEntries.forEach((entry) => {
+        new EntryPlugin(compiler.context, entry, { name: undefined }).apply(compiler);
+      });
+
+      const integrationEntry = getIntegrationEntry(this.options.overlay.sockIntegration);
+      const socketEntryData = [];
+      compiler.hooks.make.tap(
+        { name: this.constructor.name, stage: Number.POSITIVE_INFINITY },
+        (compilation) => {
+          // Exhaustively search all entries for `integrationEntry`.
+          // If found, mark those entries and the index of `integrationEntry`.
+          for (const [name, entryData] of compilation.entries.entries()) {
+            const index = entryData.dependencies.findIndex(
+              (dep) => dep.request && dep.request.includes(integrationEntry)
+            );
+            if (index !== -1) {
+              socketEntryData.push({ name, index });
+            }
+          }
+        }
+      );
+
+      // Overlay entries need to be injected AFTER integration's entry,
+      // so we will loop through everything in `finishMake` instead of `make`.
+      // This ensures we can traverse all entry points and inject stuff with the correct order.
+      addEntries.overlayEntries.forEach((entry, idx, arr) => {
+        compiler.hooks.finishMake.tapPromise(
+          { name: this.constructor.name, stage: Number.MIN_SAFE_INTEGER + (arr.length - idx - 1) },
+          (compilation) => {
+            // Only hook into the current compiler
+            if (compilation.compiler !== compiler) {
+              return Promise.resolve();
+            }
+
+            const injectData = socketEntryData.length ? socketEntryData : [{ name: undefined }];
+            return Promise.all(
+              injectData.map(({ name, index }) => {
+                return new Promise((resolve, reject) => {
+                  const options = { name };
+                  const dep = EntryPlugin.createDependency(entry, options);
+                  compilation.addEntry(compiler.context, dep, options, (err) => {
+                    if (err) return reject(err);
+
+                    // If the entry is not a global one,
+                    // and we have registered the index for integration entry,
+                    // we will reorder all entry dependencies to our desired order.
+                    // That is, to have additional entries DIRECTLY behind integration entry.
+                    if (name && typeof index !== 'undefined') {
+                      const entryData = compilation.entries.get(name);
+                      entryData.dependencies.splice(
+                        index + 1,
+                        0,
+                        entryData.dependencies.splice(entryData.dependencies.length - 1, 1)[0]
+                      );
+                    }
+
+                    resolve();
+                  });
+                });
+              })
+            ).then(() => {});
+          }
+        );
+      });
+    } else {
+      compiler.options.entry = injectRefreshEntry(compiler.options.entry, addEntries);
+    }
+
+    // Inject necessary modules and variables to bundle's global scope
+    const refreshGlobal = getRefreshGlobalScope(RuntimeGlobals || {});
+    /** @type {Record<string, string | boolean>}*/
+    const definedModules = {
+      // Mapping of react-refresh globals to Webpack runtime globals
+      $RefreshReg$: `${refreshGlobal}.register`,
+      $RefreshSig$: `${refreshGlobal}.signature`,
+      'typeof $RefreshReg$': 'function',
+      'typeof $RefreshSig$': 'function',
+
+      // Library mode
+      __react_refresh_library__: JSON.stringify(
+        Template.toIdentifier(
+          this.options.library ||
+            compiler.options.output.uniqueName ||
+            compiler.options.output.library
+        )
+      ),
+    };
+    /** @type {Record<string, string>} */
+    const providedModules = {
+      __react_refresh_utils__: require.resolve('./runtime/RefreshUtils'),
+    };
+
+    if (this.options.overlay === false) {
+      // Stub errorOverlay module so their calls can be erased
+      definedModules.__react_refresh_error_overlay__ = false;
+      definedModules.__react_refresh_polyfill_url__ = false;
+      definedModules.__react_refresh_socket__ = false;
+    } else {
+      definedModules.__react_refresh_polyfill_url__ = this.options.overlay.useURLPolyfill || false;
+
+      if (this.options.overlay.module) {
+        providedModules.__react_refresh_error_overlay__ = require.resolve(
+          this.options.overlay.module
+        );
+      }
+      if (this.options.overlay.sockIntegration) {
+        providedModules.__react_refresh_socket__ = getSocketIntegration(
+          this.options.overlay.sockIntegration
+        );
+      }
+    }
+
+    new DefinePlugin(definedModules).apply(compiler);
+    new ProvidePlugin(providedModules).apply(compiler);
+
+    const match = ModuleFilenameHelpers.matchObject.bind(undefined, this.options);
+    let loggedHotWarning = false;
+    compiler.hooks.compilation.tap(
+      this.constructor.name,
+      (compilation, { normalModuleFactory }) => {
+        // Only hook into the current compiler
+        if (compilation.compiler !== compiler) {
+          return;
+        }
+
+        // Tap into version-specific compilation hooks
+        switch (webpackVersion) {
+          case 4: {
+            const outputOptions = compilation.mainTemplate.outputOptions;
+            compilation.mainTemplate.hooks.require.tap(
+              this.constructor.name,
+              // Constructs the module template for react-refresh
+              (source, chunk, hash) => {
+                // Check for the output filename
+                // This is to ensure we are processing a JS-related chunk
+                let filename = outputOptions.filename;
+                if (typeof filename === 'function') {
+                  // Only usage of the `chunk` property is documented by Webpack.
+                  // However, some internal Webpack plugins uses other properties,
+                  // so we also pass them through to be on the safe side.
+                  filename = filename({
+                    contentHashType: 'javascript',
+                    chunk,
+                    hash,
+                  });
+                }
+
+                // Check whether the current compilation is outputting to JS,
+                // since other plugins can trigger compilations for other file types too.
+                // If we apply the transform to them, their compilation will break fatally.
+                // One prominent example of this is the HTMLWebpackPlugin.
+                // If filename is falsy, something is terribly wrong and there's nothing we can do.
+                if (!filename || !filename.includes('.js')) {
+                  return source;
+                }
+
+                // Split template source code into lines for easier processing
+                const lines = source.split('\n');
+                // Webpack generates this line when the MainTemplate is called
+                const moduleInitializationLineNumber = lines.findIndex((line) =>
+                  line.includes('modules[moduleId].call(')
+                );
+                // Unable to find call to module execution -
+                // this happens if the current module does not call MainTemplate.
+                // In this case, we will return the original source and won't mess with it.
+                if (moduleInitializationLineNumber === -1) {
+                  return source;
+                }
+
+                const moduleInterceptor = Template.asString([
+                  `${refreshGlobal}.setup(moduleId);`,
+                  'try {',
+                  Template.indent(lines[moduleInitializationLineNumber]),
+                  '} finally {',
+                  Template.indent(`${refreshGlobal}.cleanup(moduleId);`),
+                  '}',
+                ]);
+
+                return Template.asString([
+                  ...lines.slice(0, moduleInitializationLineNumber),
+                  '',
+                  outputOptions.strictModuleExceptionHandling
+                    ? Template.indent(moduleInterceptor)
+                    : moduleInterceptor,
+                  '',
+                  ...lines.slice(moduleInitializationLineNumber + 1, lines.length),
+                ]);
+              }
+            );
+
+            compilation.mainTemplate.hooks.requireExtensions.tap(
+              this.constructor.name,
+              // Setup react-refresh globals as extensions to Webpack's require function
+              (source) => {
+                return Template.asString([source, '', getRefreshGlobal(Template)]);
+              }
+            );
+
+            normalModuleFactory.hooks.afterResolve.tap(
+              this.constructor.name,
+              // Add react-refresh loader to process files that matches specified criteria
+              (data) => {
+                return injectRefreshLoader(data, {
+                  match,
+                  options: { const: false, esModule: false },
+                });
+              }
+            );
+
+            compilation.hooks.normalModuleLoader.tap(
+              // `Number.POSITIVE_INFINITY` ensures this check will run only after all other taps
+              { name: this.constructor.name, stage: Number.POSITIVE_INFINITY },
+              // Check for existence of the HMR runtime -
+              // it is the foundation to this plugin working correctly
+              (context) => {
+                if (!context.hot && !loggedHotWarning) {
+                  logger.warn(
+                    [
+                      'Hot Module Replacement (HMR) is not enabled!',
+                      'React Refresh requires HMR to function properly.',
+                    ].join(' ')
+                  );
+                  loggedHotWarning = true;
+                }
+              }
+            );
+
+            break;
+          }
+          case 5: {
+            // Set factory for EntryDependency which is used to initialise the module
+            compilation.dependencyFactories.set(EntryDependency, normalModuleFactory);
+
+            const ReactRefreshRuntimeModule = makeRefreshRuntimeModule(webpack);
+            compilation.hooks.additionalTreeRuntimeRequirements.tap(
+              this.constructor.name,
+              // Setup react-refresh globals with a Webpack runtime module
+              (chunk, runtimeRequirements) => {
+                runtimeRequirements.add(RuntimeGlobals.interceptModuleExecution);
+                runtimeRequirements.add(RuntimeGlobals.moduleCache);
+                runtimeRequirements.add(refreshGlobal);
+                compilation.addRuntimeModule(chunk, new ReactRefreshRuntimeModule());
+              }
+            );
+
+            normalModuleFactory.hooks.afterResolve.tap(
+              this.constructor.name,
+              // Add react-refresh loader to process files that matches specified criteria
+              (resolveData) => {
+                injectRefreshLoader(resolveData.createData, {
+                  match,
+                  options: {
+                    const: compilation.runtimeTemplate.supportsConst(),
+                    esModule: this.options.esModule,
+                  },
+                });
+              }
+            );
+
+            NormalModule.getCompilationHooks(compilation).loader.tap(
+              // `Infinity` ensures this check will run only after all other taps
+              { name: this.constructor.name, stage: Infinity },
+              // Check for existence of the HMR runtime -
+              // it is the foundation to this plugin working correctly
+              (context) => {
+                if (!context.hot && !loggedHotWarning) {
+                  logger.warn(
+                    [
+                      'Hot Module Replacement (HMR) is not enabled!',
+                      'React Refresh requires HMR to function properly.',
+                    ].join(' ')
+                  );
+                  loggedHotWarning = true;
+                }
+              }
+            );
+
+            break;
+          }
+          default: {
+            // Do nothing - this should be an impossible case
+          }
+        }
+      }
+    );
+  }
+}
+
+module.exports.ReactRefreshPlugin = ReactRefreshPlugin;
+module.exports = ReactRefreshPlugin;
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/options.json
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/options.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/options.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,79 @@
+{
+  "additionalProperties": false,
+  "type": "object",
+  "definitions": {
+    "Path": { "type": "string" },
+    "MatchCondition": {
+      "anyOf": [{ "instanceof": "RegExp" }, { "$ref": "#/definitions/Path" }]
+    },
+    "MatchConditions": {
+      "type": "array",
+      "items": { "$ref": "#/definitions/MatchCondition" },
+      "minItems": 1
+    },
+    "ESModuleOptions": {
+      "additionalProperties": false,
+      "type": "object",
+      "properties": {
+        "exclude": {
+          "anyOf": [
+            { "$ref": "#/definitions/MatchCondition" },
+            { "$ref": "#/definitions/MatchConditions" }
+          ]
+        },
+        "include": {
+          "anyOf": [
+            { "$ref": "#/definitions/MatchCondition" },
+            { "$ref": "#/definitions/MatchConditions" }
+          ]
+        }
+      }
+    },
+    "OverlayOptions": {
+      "additionalProperties": false,
+      "type": "object",
+      "properties": {
+        "entry": {
+          "anyOf": [{ "const": false }, { "$ref": "#/definitions/Path" }]
+        },
+        "module": {
+          "anyOf": [{ "const": false }, { "$ref": "#/definitions/Path" }]
+        },
+        "sockIntegration": {
+          "anyOf": [
+            { "const": false },
+            { "enum": ["wds", "whm", "wps"] },
+            { "$ref": "#/definitions/Path" }
+          ]
+        },
+        "sockHost": { "type": "string" },
+        "sockPath": { "type": "string" },
+        "sockPort": { "type": "number", "minimum": 0 },
+        "sockProtocol": { "enum": ["http", "https", "ws", "wss"] },
+        "useURLPolyfill": { "type": "boolean" }
+      }
+    }
+  },
+  "properties": {
+    "esModule": {
+      "anyOf": [{ "type": "boolean" }, { "$ref": "#/definitions/ESModuleOptions" }]
+    },
+    "exclude": {
+      "anyOf": [
+        { "$ref": "#/definitions/MatchCondition" },
+        { "$ref": "#/definitions/MatchConditions" }
+      ]
+    },
+    "forceEnable": { "type": "boolean" },
+    "include": {
+      "anyOf": [
+        { "$ref": "#/definitions/MatchCondition" },
+        { "$ref": "#/definitions/MatchConditions" }
+      ]
+    },
+    "library": { "type": "string" },
+    "overlay": {
+      "anyOf": [{ "type": "boolean" }, { "$ref": "#/definitions/OverlayOptions" }]
+    }
+  }
+}
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/runtime/RefreshUtils.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/runtime/RefreshUtils.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/runtime/RefreshUtils.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,286 @@
+/* global __webpack_require__ */
+var Refresh = require('react-refresh/runtime');
+
+/**
+ * Extracts exports from a webpack module object.
+ * @param {string} moduleId A Webpack module ID.
+ * @returns {*} An exports object from the module.
+ */
+function getModuleExports(moduleId) {
+  if (typeof moduleId === 'undefined') {
+    // `moduleId` is unavailable, which indicates that this module is not in the cache,
+    // which means we won't be able to capture any exports,
+    // and thus they cannot be refreshed safely.
+    // These are likely runtime or dynamically generated modules.
+    return {};
+  }
+
+  var maybeModule = __webpack_require__.c[moduleId];
+  if (typeof maybeModule === 'undefined') {
+    // `moduleId` is available but the module in cache is unavailable,
+    // which indicates the module is somehow corrupted (e.g. broken Webpacak `module` globals).
+    // We will warn the user (as this is likely a mistake) and assume they cannot be refreshed.
+    console.warn('[React Refresh] Failed to get exports for module: ' + moduleId + '.');
+    return {};
+  }
+
+  var exportsOrPromise = maybeModule.exports;
+  if (typeof Promise !== 'undefined' && exportsOrPromise instanceof Promise) {
+    return exportsOrPromise.then(function (exports) {
+      return exports;
+    });
+  }
+  return exportsOrPromise;
+}
+
+/**
+ * Calculates the signature of a React refresh boundary.
+ * If this signature changes, it's unsafe to accept the boundary.
+ *
+ * This implementation is based on the one in [Metro](https://github.com/facebook/metro/blob/907d6af22ac6ebe58572be418e9253a90665ecbd/packages/metro/src/lib/polyfills/require.js#L795-L816).
+ * @param {*} moduleExports A Webpack module exports object.
+ * @returns {string[]} A React refresh boundary signature array.
+ */
+function getReactRefreshBoundarySignature(moduleExports) {
+  var signature = [];
+  signature.push(Refresh.getFamilyByType(moduleExports));
+
+  if (moduleExports == null || typeof moduleExports !== 'object') {
+    // Exit if we can't iterate over exports.
+    return signature;
+  }
+
+  for (var key in moduleExports) {
+    if (key === '__esModule') {
+      continue;
+    }
+
+    signature.push(key);
+    signature.push(Refresh.getFamilyByType(moduleExports[key]));
+  }
+
+  return signature;
+}
+
+/**
+ * Creates a data object to be retained across refreshes.
+ * This object should not transtively reference previous exports,
+ * which can form infinite chain of objects across refreshes, which can pressure RAM.
+ *
+ * @param {*} moduleExports A Webpack module exports object.
+ * @returns {*} A React refresh boundary signature array.
+ */
+function getWebpackHotData(moduleExports) {
+  return {
+    signature: getReactRefreshBoundarySignature(moduleExports),
+    isReactRefreshBoundary: isReactRefreshBoundary(moduleExports),
+  };
+}
+
+/**
+ * Creates a helper that performs a delayed React refresh.
+ * @returns {function(function(): void): void} A debounced React refresh function.
+ */
+function createDebounceUpdate() {
+  /**
+   * A cached setTimeout handler.
+   * @type {number | undefined}
+   */
+  var refreshTimeout;
+
+  /**
+   * Performs react refresh on a delay and clears the error overlay.
+   * @param {function(): void} callback
+   * @returns {void}
+   */
+  function enqueueUpdate(callback) {
+    if (typeof refreshTimeout === 'undefined') {
+      refreshTimeout = setTimeout(function () {
+        refreshTimeout = undefined;
+        Refresh.performReactRefresh();
+        callback();
+      }, 30);
+    }
+  }
+
+  return enqueueUpdate;
+}
+
+/**
+ * Checks if all exports are likely a React component.
+ *
+ * This implementation is based on the one in [Metro](https://github.com/facebook/metro/blob/febdba2383113c88296c61e28e4ef6a7f4939fda/packages/metro/src/lib/polyfills/require.js#L748-L774).
+ * @param {*} moduleExports A Webpack module exports object.
+ * @returns {boolean} Whether the exports are React component like.
+ */
+function isReactRefreshBoundary(moduleExports) {
+  if (Refresh.isLikelyComponentType(moduleExports)) {
+    return true;
+  }
+  if (moduleExports === undefined || moduleExports === null || typeof moduleExports !== 'object') {
+    // Exit if we can't iterate over exports.
+    return false;
+  }
+
+  var hasExports = false;
+  var areAllExportsComponents = true;
+  for (var key in moduleExports) {
+    hasExports = true;
+
+    // This is the ES Module indicator flag
+    if (key === '__esModule') {
+      continue;
+    }
+
+    // We can (and have to) safely execute getters here,
+    // as Webpack manually assigns harmony exports to getters,
+    // without any side-effects attached.
+    // Ref: https://github.com/webpack/webpack/blob/b93048643fe74de2a6931755911da1212df55897/lib/MainTemplate.js#L281
+    var exportValue = moduleExports[key];
+    if (!Refresh.isLikelyComponentType(exportValue)) {
+      areAllExportsComponents = false;
+    }
+  }
+
+  return hasExports && areAllExportsComponents;
+}
+
+/**
+ * Checks if exports are likely a React component and registers them.
+ *
+ * This implementation is based on the one in [Metro](https://github.com/facebook/metro/blob/febdba2383113c88296c61e28e4ef6a7f4939fda/packages/metro/src/lib/polyfills/require.js#L818-L835).
+ * @param {*} moduleExports A Webpack module exports object.
+ * @param {string} moduleId A Webpack module ID.
+ * @returns {void}
+ */
+function registerExportsForReactRefresh(moduleExports, moduleId) {
+  if (Refresh.isLikelyComponentType(moduleExports)) {
+    // Register module.exports if it is likely a component
+    Refresh.register(moduleExports, moduleId + ' %exports%');
+  }
+
+  if (moduleExports === undefined || moduleExports === null || typeof moduleExports !== 'object') {
+    // Exit if we can't iterate over the exports.
+    return;
+  }
+
+  for (var key in moduleExports) {
+    // Skip registering the ES Module indicator
+    if (key === '__esModule') {
+      continue;
+    }
+
+    var exportValue = moduleExports[key];
+    if (Refresh.isLikelyComponentType(exportValue)) {
+      var typeID = moduleId + ' %exports% ' + key;
+      Refresh.register(exportValue, typeID);
+    }
+  }
+}
+
+/**
+ * Compares previous and next module objects to check for mutated boundaries.
+ *
+ * This implementation is based on the one in [Metro](https://github.com/facebook/metro/blob/907d6af22ac6ebe58572be418e9253a90665ecbd/packages/metro/src/lib/polyfills/require.js#L776-L792).
+ * @param {*} prevSignature The signature of the current Webpack module exports object.
+ * @param {*} nextSignature The signature of the next Webpack module exports object.
+ * @returns {boolean} Whether the React refresh boundary should be invalidated.
+ */
+function shouldInvalidateReactRefreshBoundary(prevSignature, nextSignature) {
+  if (prevSignature.length !== nextSignature.length) {
+    return true;
+  }
+
+  for (var i = 0; i < nextSignature.length; i += 1) {
+    if (prevSignature[i] !== nextSignature[i]) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+var enqueueUpdate = createDebounceUpdate();
+function executeRuntime(moduleExports, moduleId, webpackHot, refreshOverlay, isTest) {
+  registerExportsForReactRefresh(moduleExports, moduleId);
+
+  if (webpackHot) {
+    var isHotUpdate = !!webpackHot.data;
+    var prevData;
+    if (isHotUpdate) {
+      prevData = webpackHot.data.prevData;
+    }
+
+    if (isReactRefreshBoundary(moduleExports)) {
+      webpackHot.dispose(
+        /**
+         * A callback to performs a full refresh if React has unrecoverable errors,
+         * and also caches the to-be-disposed module.
+         * @param {*} data A hot module data object from Webpack HMR.
+         * @returns {void}
+         */
+        function hotDisposeCallback(data) {
+          // We have to mutate the data object to get data registered and cached
+          data.prevData = getWebpackHotData(moduleExports);
+        }
+      );
+      webpackHot.accept(
+        /**
+         * An error handler to allow self-recovering behaviours.
+         * @param {Error} error An error occurred during evaluation of a module.
+         * @returns {void}
+         */
+        function hotErrorHandler(error) {
+          if (typeof refreshOverlay !== 'undefined' && refreshOverlay) {
+            refreshOverlay.handleRuntimeError(error);
+          }
+
+          if (typeof isTest !== 'undefined' && isTest) {
+            if (window.onHotAcceptError) {
+              window.onHotAcceptError(error.message);
+            }
+          }
+
+          __webpack_require__.c[moduleId].hot.accept(hotErrorHandler);
+        }
+      );
+
+      if (isHotUpdate) {
+        if (
+          prevData &&
+          prevData.isReactRefreshBoundary &&
+          shouldInvalidateReactRefreshBoundary(
+            prevData.signature,
+            getReactRefreshBoundarySignature(moduleExports)
+          )
+        ) {
+          webpackHot.invalidate();
+        } else {
+          enqueueUpdate(
+            /**
+             * A function to dismiss the error overlay after performing React refresh.
+             * @returns {void}
+             */
+            function updateCallback() {
+              if (typeof refreshOverlay !== 'undefined' && refreshOverlay) {
+                refreshOverlay.clearRuntimeErrors();
+              }
+            }
+          );
+        }
+      }
+    } else {
+      if (isHotUpdate && typeof prevData !== 'undefined') {
+        webpackHot.invalidate();
+      }
+    }
+  }
+}
+
+module.exports = Object.freeze({
+  enqueueUpdate: enqueueUpdate,
+  executeRuntime: executeRuntime,
+  getModuleExports: getModuleExports,
+  isReactRefreshBoundary: isReactRefreshBoundary,
+  registerExportsForReactRefresh: registerExportsForReactRefresh,
+});
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/types.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/types.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/types.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,36 @@
+/**
+ * @typedef {Object} ErrorOverlayOptions
+ * @property {string | false} [entry] Path to a JS file that sets up the error overlay integration.
+ * @property {string | false} [module] The error overlay module to use.
+ * @property {string} [sockHost] The socket host to use (WDS only).
+ * @property {import('type-fest').LiteralUnion<'wds' | 'whm' | 'wps' | false, string>} [sockIntegration] Path to a JS file that sets up the Webpack socket integration.
+ * @property {string} [sockPath] The socket path to use (WDS only).
+ * @property {number} [sockPort] The socket port to use (WDS only).
+ * @property {'http' | 'https' | 'ws' | 'wss'} [sockProtocol] The socket protocol to use (WDS only).
+ * @property {boolean} [useURLPolyfill] Uses a polyfill for the DOM URL API (WDS only).
+ */
+
+/**
+ * @typedef {import('type-fest').SetRequired<ErrorOverlayOptions, 'entry' | 'module' | 'sockIntegration'>} NormalizedErrorOverlayOptions
+ */
+
+/**
+ * @typedef {Object} ReactRefreshPluginOptions
+ * @property {boolean | import('../loader/types').ESModuleOptions} [esModule] Enables strict ES Modules compatible runtime.
+ * @property {string | RegExp | Array<string | RegExp>} [exclude] Files to explicitly exclude from processing.
+ * @property {boolean} [forceEnable] Enables the plugin forcefully.
+ * @property {string | RegExp | Array<string | RegExp>} [include] Files to explicitly include for processing.
+ * @property {string} [library] Name of the library bundle.
+ * @property {boolean | ErrorOverlayOptions} [overlay] Modifies how the error overlay integration works in the plugin.
+ */
+
+/**
+ * @typedef {Object} OverlayOverrides
+ * @property {false | NormalizedErrorOverlayOptions} overlay Modifies how the error overlay integration works in the plugin.
+ */
+
+/**
+ * @typedef {import('type-fest').SetRequired<import('type-fest').Except<ReactRefreshPluginOptions, 'overlay'>, 'exclude' | 'include'> & OverlayOverrides} NormalizedPluginOptions
+ */
+
+module.exports = {};
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/utils/getAdditionalEntries.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/utils/getAdditionalEntries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/utils/getAdditionalEntries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,95 @@
+const querystring = require('querystring');
+
+/**
+ * @typedef {Object} AdditionalEntries
+ * @property {string[]} prependEntries
+ * @property {string[]} overlayEntries
+ */
+
+/**
+ * Creates an object that contains two entry arrays: the prependEntries and overlayEntries
+ * @param {Object} optionsContainer This is the container for the options to this function
+ * @param {import('../types').NormalizedPluginOptions} optionsContainer.options Configuration options for this plugin.
+ * @param {import('webpack').Compiler["options"]["devServer"]} [optionsContainer.devServer] The webpack devServer config
+ * @returns {AdditionalEntries} An object that contains the Webpack entries for prepending and the overlay feature
+ */
+function getAdditionalEntries({ devServer, options }) {
+  /** @type {Record<string, string | number>} */
+  let resourceQuery = {};
+
+  if (devServer) {
+    const { client, https, http2, sockHost, sockPath, sockPort } = devServer;
+    let { host, path, port } = devServer;
+
+    let protocol = https || http2 ? 'https' : 'http';
+    if (sockHost) host = sockHost;
+    if (sockPath) path = sockPath;
+    if (sockPort) port = sockPort;
+
+    if (client && client.webSocketURL != null) {
+      let parsedUrl = client.webSocketURL;
+      if (typeof parsedUrl === 'string') parsedUrl = new URL(parsedUrl);
+
+      let auth;
+      if (parsedUrl.username) {
+        auth = parsedUrl.username;
+        if (parsedUrl.password) {
+          auth += ':' + parsedUrl.password;
+        }
+      }
+
+      if (parsedUrl.hostname != null) {
+        host = [auth != null && auth, parsedUrl.hostname].filter(Boolean).join('@');
+      }
+      if (parsedUrl.pathname != null) {
+        path = parsedUrl.pathname;
+      }
+      if (parsedUrl.port != null) {
+        port = !['0', 'auto'].includes(String(parsedUrl.port)) ? parsedUrl.port : undefined;
+      }
+      if (parsedUrl.protocol != null) {
+        protocol = parsedUrl.protocol !== 'auto' ? parsedUrl.protocol.replace(':', '') : 'ws';
+      }
+    }
+
+    if (host) resourceQuery.sockHost = host;
+    if (path) resourceQuery.sockPath = path;
+    if (port) resourceQuery.sockPort = port;
+    resourceQuery.sockProtocol = protocol;
+  }
+
+  if (options.overlay) {
+    const { sockHost, sockPath, sockPort, sockProtocol } = options.overlay;
+    if (sockHost) resourceQuery.sockHost = sockHost;
+    if (sockPath) resourceQuery.sockPath = sockPath;
+    if (sockPort) resourceQuery.sockPort = sockPort;
+    if (sockProtocol) resourceQuery.sockProtocol = sockProtocol;
+  }
+
+  // We don't need to URI encode the resourceQuery as it will be parsed by Webpack
+  const queryString = querystring.stringify(resourceQuery, undefined, undefined, {
+    /**
+     * @param {string} string
+     * @returns {string}
+     */
+    encodeURIComponent(string) {
+      return string;
+    },
+  });
+
+  const prependEntries = [
+    // React-refresh runtime
+    require.resolve('../../client/ReactRefreshEntry'),
+  ];
+
+  const overlayEntries = [
+    // Error overlay runtime
+    options.overlay &&
+      options.overlay.entry &&
+      `${require.resolve(options.overlay.entry)}${queryString ? `?${queryString}` : ''}`,
+  ].filter(Boolean);
+
+  return { prependEntries, overlayEntries };
+}
+
+module.exports = getAdditionalEntries;
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/utils/getIntegrationEntry.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/utils/getIntegrationEntry.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/utils/getIntegrationEntry.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,22 @@
+/**
+ * Gets entry point of a supported socket integration.
+ * @param {'wds' | 'whm' | 'wps' | string} integrationType A valid socket integration type or a path to a module.
+ * @returns {string | undefined} Path to the resolved integration entry point.
+ */
+function getIntegrationEntry(integrationType) {
+  let resolvedEntry;
+  switch (integrationType) {
+    case 'whm': {
+      resolvedEntry = 'webpack-hot-middleware/client';
+      break;
+    }
+    case 'wps': {
+      resolvedEntry = 'webpack-plugin-serve/client';
+      break;
+    }
+  }
+
+  return resolvedEntry;
+}
+
+module.exports = getIntegrationEntry;
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/utils/getRefreshGlobal.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/utils/getRefreshGlobal.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/utils/getRefreshGlobal.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,96 @@
+const { getRefreshGlobalScope } = require('../globals');
+
+/**
+ * @typedef {Object} RuntimeTemplate
+ * @property {function(string, string[]): string} basicFunction
+ * @property {function(): boolean} supportsConst
+ * @property {function(string, string=): string} returningFunction
+ */
+
+/**
+ * Generates the refresh global runtime template.
+ * @param {import('webpack').Template} Template The template helpers.
+ * @param {Record<string, string>} [RuntimeGlobals] The runtime globals.
+ * @param {RuntimeTemplate} [RuntimeTemplate] The runtime template helpers.
+ * @returns {string} The refresh global runtime template.
+ */
+function getRefreshGlobal(
+  Template,
+  RuntimeGlobals = {},
+  RuntimeTemplate = {
+    basicFunction(args, body) {
+      return `function(${args}) {\n${Template.indent(body)}\n}`;
+    },
+    supportsConst() {
+      return false;
+    },
+    returningFunction(returnValue, args = '') {
+      return `function(${args}) { return ${returnValue}; }`;
+    },
+  }
+) {
+  const declaration = RuntimeTemplate.supportsConst() ? 'const' : 'var';
+  const refreshGlobal = getRefreshGlobalScope(RuntimeGlobals);
+  return Template.asString([
+    `${refreshGlobal} = {`,
+    Template.indent([
+      // Lifecycle methods - They should be specific per module and restored after module execution.
+      // These stubs ensure unwanted calls (e.g. unsupported patterns, broken transform) would not error out.
+      // If the current module is processed by our loader,
+      // they will be swapped in place during module initialisation by the `setup` method below.
+      `register: ${RuntimeTemplate.returningFunction('undefined')},`,
+      `signature: ${RuntimeTemplate.returningFunction(
+        RuntimeTemplate.returningFunction('type', 'type')
+      )},`,
+      // Runtime - This should be a singleton and persist throughout the lifetime of the app.
+      // This stub ensures calls to `runtime` would not error out.
+      // If any module within the bundle is processed by our loader,
+      // it will be swapped in place via an injected import.
+      'runtime: {',
+      Template.indent([
+        `createSignatureFunctionForTransform: ${RuntimeTemplate.returningFunction(
+          RuntimeTemplate.returningFunction('type', 'type')
+        )},`,
+        `register: ${RuntimeTemplate.returningFunction('undefined')}`,
+      ]),
+      '},',
+      // Setup - This handles initialisation of the global runtime.
+      // It should never be touched throughout the lifetime of the app.
+      `setup: ${RuntimeTemplate.basicFunction('currentModuleId', [
+        // Store all previous values for fields on `refreshGlobal` -
+        // this allows proper restoration in the `cleanup` phase.
+        `${declaration} prevModuleId = ${refreshGlobal}.moduleId;`,
+        `${declaration} prevRegister = ${refreshGlobal}.register;`,
+        `${declaration} prevSignature = ${refreshGlobal}.signature;`,
+        `${declaration} prevCleanup = ${refreshGlobal}.cleanup;`,
+        '',
+        `${refreshGlobal}.moduleId = currentModuleId;`,
+        '',
+        `${refreshGlobal}.register = ${RuntimeTemplate.basicFunction('type, id', [
+          `${declaration} typeId = currentModuleId + " " + id;`,
+          `${refreshGlobal}.runtime.register(type, typeId);`,
+        ])}`,
+        '',
+        `${refreshGlobal}.signature = ${RuntimeTemplate.returningFunction(
+          `${refreshGlobal}.runtime.createSignatureFunctionForTransform()`
+        )};`,
+        '',
+        `${refreshGlobal}.cleanup = ${RuntimeTemplate.basicFunction('cleanupModuleId', [
+          // Only cleanup if the module IDs match.
+          // In rare cases, it might get called in another module's `cleanup` phase.
+          'if (currentModuleId === cleanupModuleId) {',
+          Template.indent([
+            `${refreshGlobal}.moduleId = prevModuleId;`,
+            `${refreshGlobal}.register = prevRegister;`,
+            `${refreshGlobal}.signature = prevSignature;`,
+            `${refreshGlobal}.cleanup = prevCleanup;`,
+          ]),
+          '}',
+        ])}`,
+      ])}`,
+    ]),
+    '};',
+  ]);
+}
+
+module.exports = getRefreshGlobal;
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/utils/getSocketIntegration.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/utils/getSocketIntegration.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/utils/getSocketIntegration.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,30 @@
+/**
+ * Gets the socket integration to use for Webpack messages.
+ * @param {'wds' | 'whm' | 'wps' | string} integrationType A valid socket integration type or a path to a module.
+ * @returns {string} Path to the resolved socket integration module.
+ */
+function getSocketIntegration(integrationType) {
+  let resolvedSocketIntegration;
+  switch (integrationType) {
+    case 'wds': {
+      resolvedSocketIntegration = require.resolve('../../sockets/WDSSocket');
+      break;
+    }
+    case 'whm': {
+      resolvedSocketIntegration = require.resolve('../../sockets/WHMEventSource');
+      break;
+    }
+    case 'wps': {
+      resolvedSocketIntegration = require.resolve('../../sockets/WPSSocket');
+      break;
+    }
+    default: {
+      resolvedSocketIntegration = require.resolve(integrationType);
+      break;
+    }
+  }
+
+  return resolvedSocketIntegration;
+}
+
+module.exports = getSocketIntegration;
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/utils/index.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/utils/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/utils/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,19 @@
+const getAdditionalEntries = require('./getAdditionalEntries');
+const getIntegrationEntry = require('./getIntegrationEntry');
+const getRefreshGlobal = require('./getRefreshGlobal');
+const getSocketIntegration = require('./getSocketIntegration');
+const injectRefreshEntry = require('./injectRefreshEntry');
+const injectRefreshLoader = require('./injectRefreshLoader');
+const makeRefreshRuntimeModule = require('./makeRefreshRuntimeModule');
+const normalizeOptions = require('./normalizeOptions');
+
+module.exports = {
+  getAdditionalEntries,
+  getIntegrationEntry,
+  getRefreshGlobal,
+  getSocketIntegration,
+  injectRefreshEntry,
+  injectRefreshLoader,
+  makeRefreshRuntimeModule,
+  normalizeOptions,
+};
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/utils/injectRefreshEntry.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/utils/injectRefreshEntry.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/utils/injectRefreshEntry.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,98 @@
+/** @typedef {string | string[] | import('webpack').Entry} StaticEntry */
+/** @typedef {StaticEntry | import('webpack').EntryFunc} WebpackEntry */
+
+const EntryParseError = new Error(
+  [
+    '[ReactRefreshPlugin]',
+    'Failed to parse the Webpack `entry` object!',
+    'Please ensure the `entry` option in your Webpack config is specified.',
+  ].join(' ')
+);
+
+/**
+ * Webpack entries related to socket integrations.
+ * They have to run before any code that sets up the error overlay.
+ * @type {string[]}
+ */
+const socketEntries = [
+  'webpack-dev-server/client',
+  'webpack-hot-middleware/client',
+  'webpack-plugin-serve/client',
+  'react-dev-utils/webpackHotDevClient',
+];
+
+/**
+ * Checks if a Webpack entry string is related to socket integrations.
+ * @param {string} entry A Webpack entry string.
+ * @returns {boolean} Whether the entry is related to socket integrations.
+ */
+function isSocketEntry(entry) {
+  return socketEntries.some((socketEntry) => entry.includes(socketEntry));
+}
+
+/**
+ * Injects an entry to the bundle for react-refresh.
+ * @param {WebpackEntry} [originalEntry] A Webpack entry object.
+ * @param {import('./getAdditionalEntries').AdditionalEntries} additionalEntries An object that contains the Webpack entries for prepending and the overlay feature
+ * @returns {WebpackEntry} An injected entry object.
+ */
+function injectRefreshEntry(originalEntry, additionalEntries) {
+  const { prependEntries, overlayEntries } = additionalEntries;
+
+  // Single string entry point
+  if (typeof originalEntry === 'string') {
+    if (isSocketEntry(originalEntry)) {
+      return [...prependEntries, originalEntry, ...overlayEntries];
+    }
+
+    return [...prependEntries, ...overlayEntries, originalEntry];
+  }
+  // Single array entry point
+  if (Array.isArray(originalEntry)) {
+    if (originalEntry.length === 0) {
+      throw EntryParseError;
+    }
+
+    const socketEntryIndex = originalEntry.findIndex(isSocketEntry);
+
+    let socketAndPrecedingEntries = [];
+    if (socketEntryIndex !== -1) {
+      socketAndPrecedingEntries = originalEntry.splice(0, socketEntryIndex + 1);
+    }
+
+    return [...prependEntries, ...socketAndPrecedingEntries, ...overlayEntries, ...originalEntry];
+  }
+  // Multiple entry points
+  if (typeof originalEntry === 'object') {
+    const entries = Object.entries(originalEntry);
+    if (entries.length === 0) {
+      throw EntryParseError;
+    }
+
+    return entries.reduce(
+      (acc, [curKey, curEntry]) => ({
+        ...acc,
+        [curKey]:
+          typeof curEntry === 'object' && curEntry.import
+            ? {
+                ...curEntry,
+                import: injectRefreshEntry(curEntry.import, additionalEntries),
+              }
+            : injectRefreshEntry(curEntry, additionalEntries),
+      }),
+      {}
+    );
+  }
+  // Dynamic entry points
+  if (typeof originalEntry === 'function') {
+    return (...args) =>
+      Promise.resolve(originalEntry(...args)).then((resolvedEntry) =>
+        injectRefreshEntry(resolvedEntry, additionalEntries)
+      );
+  }
+
+  throw EntryParseError;
+}
+
+module.exports = injectRefreshEntry;
+module.exports.socketEntries = socketEntries;
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/utils/injectRefreshLoader.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/utils/injectRefreshLoader.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/utils/injectRefreshLoader.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,58 @@
+const path = require('path');
+
+/**
+ * @callback MatchObject
+ * @param {string} [str]
+ * @returns {boolean}
+ */
+
+/**
+ * @typedef {Object} InjectLoaderOptions
+ * @property {MatchObject} match A function to include/exclude files to be processed.
+ * @property {import('../../loader/types').ReactRefreshLoaderOptions} [options] Options passed to the loader.
+ */
+
+const resolvedLoader = require.resolve('../../loader');
+const reactRefreshPath = path.dirname(require.resolve('react-refresh'));
+const refreshUtilsPath = path.join(__dirname, '../runtime/RefreshUtils');
+
+/**
+ * Injects refresh loader to all JavaScript-like and user-specified files.
+ * @param {*} moduleData Module factory creation data.
+ * @param {InjectLoaderOptions} injectOptions Options to alter how the loader is injected.
+ * @returns {*} The injected module factory creation data.
+ */
+function injectRefreshLoader(moduleData, injectOptions) {
+  const { match, options } = injectOptions;
+
+  // Include and exclude user-specified files
+  if (!match(moduleData.matchResource || moduleData.resource)) return moduleData;
+  // Include and exclude dynamically generated modules from other loaders
+  if (moduleData.matchResource && !match(moduleData.request)) return moduleData;
+  // Exclude files referenced as assets
+  if (moduleData.type.includes('asset')) return moduleData;
+  // Check to prevent double injection
+  if (moduleData.loaders.find(({ loader }) => loader === resolvedLoader)) return moduleData;
+  // Skip react-refresh and the plugin's runtime utils to prevent self-referencing -
+  // this is useful when using the plugin as a direct dependency,
+  // or when node_modules are specified to be processed.
+  if (
+    moduleData.resource.includes(reactRefreshPath) ||
+    moduleData.resource.includes(refreshUtilsPath)
+  ) {
+    return moduleData;
+  }
+
+  // As we inject runtime code for each module,
+  // it is important to run the injected loader after everything.
+  // This way we can ensure that all code-processing have been done,
+  // and we won't risk breaking tools like Flow or ESLint.
+  moduleData.loaders.unshift({
+    loader: resolvedLoader,
+    options,
+  });
+
+  return moduleData;
+}
+
+module.exports = injectRefreshLoader;
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/utils/makeRefreshRuntimeModule.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/utils/makeRefreshRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/utils/makeRefreshRuntimeModule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,96 @@
+/**
+ * Makes a runtime module to intercept module execution for React Refresh.
+ * This module creates an isolated `__webpack_require__` function for each module,
+ * and injects a `$Refresh$` object into it for use by React Refresh.
+ * @param {import('webpack')} webpack The Webpack exports.
+ * @returns {new () => import('webpack').RuntimeModule} The runtime module class.
+ */
+function makeRefreshRuntimeModule(webpack) {
+  return class ReactRefreshRuntimeModule extends webpack.RuntimeModule {
+    constructor() {
+      // Second argument is the `stage` for this runtime module -
+      // we'll use the same stage as Webpack's HMR runtime module for safety.
+      super('react refresh', webpack.RuntimeModule.STAGE_BASIC);
+    }
+
+    /**
+     * @returns {string} runtime code
+     */
+    generate() {
+      if (!this.compilation) throw new Error('Webpack compilation missing!');
+
+      const { runtimeTemplate } = this.compilation;
+      const declareVar = runtimeTemplate.supportsConst() ? 'const' : 'var';
+      return webpack.Template.asString([
+        `${declareVar} setup = ${runtimeTemplate.basicFunction('moduleId', [
+          `${declareVar} refresh = {`,
+          webpack.Template.indent([
+            `moduleId: moduleId,`,
+            `register: ${runtimeTemplate.basicFunction('type, id', [
+              `${declareVar} typeId = moduleId + " " + id;`,
+              `refresh.runtime.register(type, typeId);`,
+            ])},`,
+            `signature: ${runtimeTemplate.returningFunction(
+              'refresh.runtime.createSignatureFunctionForTransform()'
+            )},`,
+            `runtime: {`,
+            webpack.Template.indent([
+              `createSignatureFunctionForTransform: ${runtimeTemplate.returningFunction(
+                runtimeTemplate.returningFunction('type', 'type')
+              )},`,
+              `register: ${runtimeTemplate.emptyFunction()}`,
+            ]),
+            `},`,
+          ]),
+          `};`,
+          `return refresh;`,
+        ])}`,
+        '',
+        `${webpack.RuntimeGlobals.interceptModuleExecution}.push(${runtimeTemplate.basicFunction(
+          'options',
+          [
+            `${declareVar} originalFactory = options.factory;`,
+            // Using a function declaration -
+            // ensures `this` would propagate for modules relying on it
+            `options.factory = function(moduleObject, moduleExports, webpackRequire) {`,
+            webpack.Template.indent([
+              // Our require function delegates to the original require function
+              `${declareVar} hotRequire = ${runtimeTemplate.returningFunction(
+                'webpackRequire(request)',
+                'request'
+              )};`,
+              // The propery descriptor factory below ensures all properties but `$Refresh$`
+              // are proxied through to the original require function
+              `${declareVar} createPropertyDescriptor = ${runtimeTemplate.basicFunction('name', [
+                `return {`,
+                webpack.Template.indent([
+                  `configurable: true,`,
+                  `enumerable: true,`,
+                  `get: ${runtimeTemplate.returningFunction('webpackRequire[name]')},`,
+                  `set: ${runtimeTemplate.basicFunction('value', [
+                    'webpackRequire[name] = value;',
+                  ])},`,
+                ]),
+                `};`,
+              ])};`,
+              `for (${declareVar} name in webpackRequire) {`,
+              webpack.Template.indent([
+                `if (Object.prototype.hasOwnProperty.call(webpackRequire, name) && name !== "$Refresh$") {`,
+                webpack.Template.indent([
+                  `Object.defineProperty(hotRequire, name, createPropertyDescriptor(name));`,
+                ]),
+                `}`,
+              ]),
+              `}`,
+              `hotRequire.$Refresh$ = setup(options.id);`,
+              `originalFactory.call(this, moduleObject, moduleExports, hotRequire);`,
+            ]),
+            '};',
+          ]
+        )});`,
+      ]);
+    }
+  };
+}
+
+module.exports = makeRefreshRuntimeModule;
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/utils/normalizeOptions.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/utils/normalizeOptions.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/utils/normalizeOptions.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,44 @@
+const { d, n } = require('../../options');
+
+/**
+ * Normalizes the options for the plugin.
+ * @param {import('../types').ReactRefreshPluginOptions} options Non-normalized plugin options.
+ * @returns {import('../types').NormalizedPluginOptions} Normalized plugin options.
+ */
+const normalizeOptions = (options) => {
+  d(options, 'exclude', /node_modules/i);
+  d(options, 'include', /\.([cm]js|[jt]sx?|flow)$/i);
+  d(options, 'forceEnable');
+  d(options, 'library');
+
+  n(options, 'overlay', (overlay) => {
+    /** @type {import('../types').NormalizedErrorOverlayOptions} */
+    const defaults = {
+      entry: require.resolve('../../client/ErrorOverlayEntry'),
+      module: require.resolve('../../overlay'),
+      sockIntegration: 'wds',
+    };
+
+    if (overlay === false) {
+      return false;
+    }
+    if (typeof overlay === 'undefined' || overlay === true) {
+      return defaults;
+    }
+
+    d(overlay, 'entry', defaults.entry);
+    d(overlay, 'module', defaults.module);
+    d(overlay, 'sockIntegration', defaults.sockIntegration);
+    d(overlay, 'sockHost');
+    d(overlay, 'sockPath');
+    d(overlay, 'sockPort');
+    d(overlay, 'sockProtocol');
+    d(options, 'useURLPolyfill');
+
+    return overlay;
+  });
+
+  return options;
+};
+
+module.exports = normalizeOptions;
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/index.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,108 @@
+// This is a patch for mozilla/source-map#349 -
+// internally, it uses the existence of the `fetch` global to toggle browser behaviours.
+// That check, however, will break when `fetch` polyfills are used for SSR setups.
+// We "reset" the polyfill here to ensure it won't interfere with source-map generation.
+const originalFetch = global.fetch;
+delete global.fetch;
+
+const { getOptions } = require('loader-utils');
+const { validate: validateOptions } = require('schema-utils');
+const { SourceMapConsumer, SourceNode } = require('source-map');
+const {
+  getIdentitySourceMap,
+  getModuleSystem,
+  getRefreshModuleRuntime,
+  normalizeOptions,
+} = require('./utils');
+const schema = require('./options.json');
+
+const RefreshRuntimePath = require
+  .resolve('react-refresh')
+  .replace(/\\/g, '/')
+  .replace(/'/g, "\\'");
+
+/**
+ * A simple Webpack loader to inject react-refresh HMR code into modules.
+ *
+ * [Reference for Loader API](https://webpack.js.org/api/loaders/)
+ * @this {import('webpack').LoaderContext<import('./types').ReactRefreshLoaderOptions>}
+ * @param {string} source The original module source code.
+ * @param {import('source-map').RawSourceMap} [inputSourceMap] The source map of the module.
+ * @param {*} [meta] The loader metadata passed in.
+ * @returns {void}
+ */
+function ReactRefreshLoader(source, inputSourceMap, meta) {
+  let options = getOptions(this);
+  validateOptions(schema, options, {
+    baseDataPath: 'options',
+    name: 'React Refresh Loader',
+  });
+
+  options = normalizeOptions(options);
+
+  const callback = this.async();
+
+  const { ModuleFilenameHelpers, Template } = this._compiler.webpack || require('webpack');
+
+  const RefreshSetupRuntimes = {
+    cjs: Template.asString(
+      `__webpack_require__.$Refresh$.runtime = require('${RefreshRuntimePath}');`
+    ),
+    esm: Template.asString([
+      `import * as __react_refresh_runtime__ from '${RefreshRuntimePath}';`,
+      `__webpack_require__.$Refresh$.runtime = __react_refresh_runtime__;`,
+    ]),
+  };
+
+  /**
+   * @this {import('webpack').LoaderContext<import('./types').ReactRefreshLoaderOptions>}
+   * @param {string} source
+   * @param {import('source-map').RawSourceMap} [inputSourceMap]
+   * @returns {Promise<[string, import('source-map').RawSourceMap]>}
+   */
+  async function _loader(source, inputSourceMap) {
+    /** @type {'esm' | 'cjs'} */
+    const moduleSystem = await getModuleSystem.call(this, ModuleFilenameHelpers, options);
+
+    const RefreshSetupRuntime = RefreshSetupRuntimes[moduleSystem];
+    const RefreshModuleRuntime = getRefreshModuleRuntime(Template, {
+      const: options.const,
+      moduleSystem,
+    });
+
+    if (this.sourceMap) {
+      let originalSourceMap = inputSourceMap;
+      if (!originalSourceMap) {
+        originalSourceMap = getIdentitySourceMap(source, this.resourcePath);
+      }
+
+      return SourceMapConsumer.with(originalSourceMap, undefined, (consumer) => {
+        const node = SourceNode.fromStringWithSourceMap(source, consumer);
+
+        node.prepend([RefreshSetupRuntime, '\n\n']);
+        node.add(['\n\n', RefreshModuleRuntime]);
+
+        const { code, map } = node.toStringWithSourceMap();
+        return [code, map.toJSON()];
+      });
+    } else {
+      return [[RefreshSetupRuntime, source, RefreshModuleRuntime].join('\n\n'), inputSourceMap];
+    }
+  }
+
+  _loader.call(this, source, inputSourceMap).then(
+    ([code, map]) => {
+      callback(null, code, map, meta);
+    },
+    (error) => {
+      callback(error);
+    }
+  );
+}
+
+module.exports = ReactRefreshLoader;
+
+// Restore the original value of the `fetch` global, if it exists
+if (originalFetch) {
+  global.fetch = originalFetch;
+}
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/options.json
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/options.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/options.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,37 @@
+{
+  "additionalProperties": false,
+  "type": "object",
+  "definitions": {
+    "MatchCondition": {
+      "anyOf": [{ "instanceof": "RegExp", "tsType": "RegExp" }, { "$ref": "#/definitions/Path" }]
+    },
+    "MatchConditions": {
+      "type": "array",
+      "items": { "$ref": "#/definitions/MatchCondition" },
+      "minItems": 1
+    },
+    "Path": { "type": "string" },
+    "ESModuleOptions": {
+      "additionalProperties": false,
+      "type": "object",
+      "properties": {
+        "exclude": {
+          "anyOf": [
+            { "$ref": "#/definitions/MatchCondition" },
+            { "$ref": "#/definitions/MatchConditions" }
+          ]
+        },
+        "include": {
+          "anyOf": [
+            { "$ref": "#/definitions/MatchCondition" },
+            { "$ref": "#/definitions/MatchConditions" }
+          ]
+        }
+      }
+    }
+  },
+  "properties": {
+    "const": { "type": "boolean" },
+    "esModule": { "anyOf": [{ "type": "boolean" }, { "$ref": "#/definitions/ESModuleOptions" }] }
+  }
+}
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/types.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/types.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/types.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,17 @@
+/**
+ * @typedef {Object} ESModuleOptions
+ * @property {string | RegExp | Array<string | RegExp>} [exclude] Files to explicitly exclude from flagged as ES Modules.
+ * @property {string | RegExp | Array<string | RegExp>} [include] Files to explicitly include for flagged as ES Modules.
+ */
+
+/**
+ * @typedef {Object} ReactRefreshLoaderOptions
+ * @property {boolean} [const] Enables usage of ES6 `const` and `let` in generated runtime code.
+ * @property {boolean | ESModuleOptions} [esModule] Enables strict ES Modules compatible runtime.
+ */
+
+/**
+ * @typedef {import('type-fest').SetRequired<ReactRefreshLoaderOptions, 'const'>} NormalizedLoaderOptions
+ */
+
+module.exports = {};
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/utils/getIdentitySourceMap.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/utils/getIdentitySourceMap.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/utils/getIdentitySourceMap.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,30 @@
+const { SourceMapGenerator } = require('source-map');
+
+/**
+ * Generates an identity source map from a source file.
+ * @param {string} source The content of the source file.
+ * @param {string} resourcePath The name of the source file.
+ * @returns {import('source-map').RawSourceMap} The identity source map.
+ */
+function getIdentitySourceMap(source, resourcePath) {
+  const sourceMap = new SourceMapGenerator();
+  sourceMap.setSourceContent(resourcePath, source);
+
+  source.split('\n').forEach((line, index) => {
+    sourceMap.addMapping({
+      source: resourcePath,
+      original: {
+        line: index + 1,
+        column: 0,
+      },
+      generated: {
+        line: index + 1,
+        column: 0,
+      },
+    });
+  });
+
+  return sourceMap.toJSON();
+}
+
+module.exports = getIdentitySourceMap;
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/utils/getModuleSystem.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/utils/getModuleSystem.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/utils/getModuleSystem.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,128 @@
+const { promises: fsPromises } = require('fs');
+const path = require('path');
+
+/** @type {Map<string, string | undefined>} */
+let packageJsonTypeMap = new Map();
+
+/**
+ * Infers the current active module system from loader context and options.
+ * @this {import('webpack').loader.LoaderContext}
+ * @param {import('webpack').ModuleFilenameHelpers} ModuleFilenameHelpers Webpack's module filename helpers.
+ * @param {import('../types').NormalizedLoaderOptions} options The normalized loader options.
+ * @return {Promise<'esm' | 'cjs'>} The inferred module system.
+ */
+async function getModuleSystem(ModuleFilenameHelpers, options) {
+  // Check loader options -
+  // if `esModule` is set we don't have to do extra guess work.
+  switch (typeof options.esModule) {
+    case 'boolean': {
+      return options.esModule ? 'esm' : 'cjs';
+    }
+    case 'object': {
+      if (
+        options.esModule.include &&
+        ModuleFilenameHelpers.matchPart(this.resourcePath, options.esModule.include)
+      ) {
+        return 'esm';
+      }
+      if (
+        options.esModule.exclude &&
+        ModuleFilenameHelpers.matchPart(this.resourcePath, options.esModule.exclude)
+      ) {
+        return 'cjs';
+      }
+
+      break;
+    }
+    default: // Do nothing
+  }
+
+  // Check current resource's extension
+  if (/\.mjs$/.test(this.resourcePath)) return 'esm';
+  if (/\.cjs$/.test(this.resourcePath)) return 'cjs';
+
+  if (typeof this.addMissingDependency !== 'function') {
+    // This is Webpack 4 which does not support `import.meta`.
+    // We assume `.js` files are CommonJS because the output cannot be ESM anyway.
+    return 'cjs';
+  }
+
+  // We will assume CommonJS if we cannot determine otherwise
+  let packageJsonType = '';
+
+  // We begin our search for relevant `package.json` files,
+  // at the directory of the resource being loaded.
+  // These paths should already be resolved,
+  // but we resolve them again to ensure we are dealing with an aboslute path.
+  const resourceContext = path.dirname(this.resourcePath);
+  let searchPath = resourceContext;
+  let previousSearchPath = '';
+  // We start our search just above the root context of the webpack compilation
+  const stopPath = path.dirname(this.rootContext);
+
+  // If the module context is a resolved symlink outside the `rootContext` path,
+  // then we will never find the `stopPath` - so we also halt when we hit the root.
+  // Note that there is a potential that the wrong `package.json` is found in some pathalogical cases,
+  // such as a folder that is conceptually a package + does not have an ancestor `package.json`,
+  // but there exists a `package.json` higher up.
+  // This might happen if you have a folder of utility JS files that you symlink but did not organize as a package.
+  // We consider this an unsupported edge case for now.
+  while (searchPath !== stopPath && searchPath !== previousSearchPath) {
+    // If we have already determined the `package.json` type for this path we can stop searching.
+    // We do however still need to cache the found value,
+    // from the `resourcePath` folder up to the matching `searchPath`,
+    // to avoid retracing these steps when processing sibling resources.
+    if (packageJsonTypeMap.has(searchPath)) {
+      packageJsonType = packageJsonTypeMap.get(searchPath);
+
+      let currentPath = resourceContext;
+      while (currentPath !== searchPath) {
+        // We set the found type at least level from `resourcePath` folder up to the matching `searchPath`
+        packageJsonTypeMap.set(currentPath, packageJsonType);
+        currentPath = path.dirname(currentPath);
+      }
+      break;
+    }
+
+    let packageJsonPath = path.join(searchPath, 'package.json');
+    try {
+      const packageSource = await fsPromises.readFile(packageJsonPath, 'utf-8');
+      try {
+        const packageObject = JSON.parse(packageSource);
+
+        // Any package.json is sufficient as long as it can be parsed.
+        // If it does not explicitly have a `type: "module"` it will be assumed to be CommonJS.
+        packageJsonType = typeof packageObject.type === 'string' ? packageObject.type : '';
+        packageJsonTypeMap.set(searchPath, packageJsonType);
+
+        // We set the type in the cache for all paths from the `resourcePath` folder,
+        // up to the matching `searchPath` to avoid retracing these steps when processing sibling resources.
+        let currentPath = resourceContext;
+        while (currentPath !== searchPath) {
+          packageJsonTypeMap.set(currentPath, packageJsonType);
+          currentPath = path.dirname(currentPath);
+        }
+      } catch (e) {
+        // `package.json` exists but could not be parsed.
+        // We track it as a dependency so we can reload if this file changes.
+      }
+
+      this.addDependency(packageJsonPath);
+      break;
+    } catch (e) {
+      // `package.json` does not exist.
+      // We track it as a missing dependency so we can reload if this file is added.
+      this.addMissingDependency(packageJsonPath);
+    }
+
+    // Try again at the next level up
+    previousSearchPath = searchPath;
+    searchPath = path.dirname(searchPath);
+  }
+
+  // Check `package.json` for the `type` field -
+  // fallback to use `cjs` for anything ambiguous.
+  return packageJsonType === 'module' ? 'esm' : 'cjs';
+}
+
+module.exports = getModuleSystem;
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/utils/getRefreshModuleRuntime.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/utils/getRefreshModuleRuntime.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/utils/getRefreshModuleRuntime.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,63 @@
+/**
+ * @typedef ModuleRuntimeOptions {Object}
+ * @property {boolean} const Use ES6 `const` and `let` in generated runtime code.
+ * @property {'cjs' | 'esm'} moduleSystem The module system to be used.
+ */
+
+/**
+ * Generates code appended to each JS-like module for react-refresh capabilities.
+ *
+ * `__react_refresh_utils__` will be replaced with actual utils during source parsing by `webpack.ProvidePlugin`.
+ *
+ * [Reference for Runtime Injection](https://github.com/webpack/webpack/blob/b07d3b67d2252f08e4bb65d354a11c9b69f8b434/lib/HotModuleReplacementPlugin.js#L419)
+ * [Reference for HMR Error Recovery](https://github.com/webpack/webpack/issues/418#issuecomment-490296365)
+ *
+ * @param {import('webpack').Template} Webpack's templating helpers.
+ * @param {ModuleRuntimeOptions} options The refresh module runtime options.
+ * @returns {string} The refresh module runtime template.
+ */
+function getRefreshModuleRuntime(Template, options) {
+  const constDeclaration = options.const ? 'const' : 'var';
+  const letDeclaration = options.const ? 'let' : 'var';
+  const webpackHot = options.moduleSystem === 'esm' ? 'import.meta.webpackHot' : 'module.hot';
+  return Template.asString([
+    `${constDeclaration} $ReactRefreshModuleId$ = __webpack_require__.$Refresh$.moduleId;`,
+    `${constDeclaration} $ReactRefreshCurrentExports$ = __react_refresh_utils__.getModuleExports(`,
+    Template.indent('$ReactRefreshModuleId$'),
+    ');',
+    '',
+    'function $ReactRefreshModuleRuntime$(exports) {',
+    Template.indent([
+      `if (${webpackHot}) {`,
+      Template.indent([
+        `${letDeclaration} errorOverlay;`,
+        "if (typeof __react_refresh_error_overlay__ !== 'undefined') {",
+        Template.indent('errorOverlay = __react_refresh_error_overlay__;'),
+        '}',
+        `${letDeclaration} testMode;`,
+        "if (typeof __react_refresh_test__ !== 'undefined') {",
+        Template.indent('testMode = __react_refresh_test__;'),
+        '}',
+        'return __react_refresh_utils__.executeRuntime(',
+        Template.indent([
+          'exports,',
+          '$ReactRefreshModuleId$,',
+          `${webpackHot},`,
+          'errorOverlay,',
+          'testMode',
+        ]),
+        ');',
+      ]),
+      '}',
+    ]),
+    '}',
+    '',
+    "if (typeof Promise !== 'undefined' && $ReactRefreshCurrentExports$ instanceof Promise) {",
+    Template.indent('$ReactRefreshCurrentExports$.then($ReactRefreshModuleRuntime$);'),
+    '} else {',
+    Template.indent('$ReactRefreshModuleRuntime$($ReactRefreshCurrentExports$);'),
+    '}',
+  ]);
+}
+
+module.exports = getRefreshModuleRuntime;
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/utils/index.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/utils/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/utils/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,11 @@
+const getIdentitySourceMap = require('./getIdentitySourceMap');
+const getModuleSystem = require('./getModuleSystem');
+const getRefreshModuleRuntime = require('./getRefreshModuleRuntime');
+const normalizeOptions = require('./normalizeOptions');
+
+module.exports = {
+  getIdentitySourceMap,
+  getModuleSystem,
+  getRefreshModuleRuntime,
+  normalizeOptions,
+};
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/utils/normalizeOptions.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/utils/normalizeOptions.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/utils/normalizeOptions.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,25 @@
+const { d, n } = require('../../options');
+
+/**
+ * Normalizes the options for the loader.
+ * @param {import('../types').ReactRefreshLoaderOptions} options Non-normalized loader options.
+ * @returns {import('../types').NormalizedLoaderOptions} Normalized loader options.
+ */
+const normalizeOptions = (options) => {
+  d(options, 'const', false);
+
+  n(options, 'esModule', (esModule) => {
+    if (typeof esModule === 'boolean' || typeof esModule === 'undefined') {
+      return esModule;
+    }
+
+    d(esModule, 'include');
+    d(esModule, 'exclude');
+
+    return esModule;
+  });
+
+  return options;
+};
+
+module.exports = normalizeOptions;
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/options/index.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/options/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/options/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,32 @@
+/**
+ * Sets a constant default value for the property when it is undefined.
+ * @template T
+ * @template {keyof T} Property
+ * @param {T} object An object.
+ * @param {Property} property A property of the provided object.
+ * @param {T[Property]} [defaultValue] The default value to set for the property.
+ * @returns {T[Property]} The defaulted property value.
+ */
+const d = (object, property, defaultValue) => {
+  if (typeof object[property] === 'undefined' && typeof defaultValue !== 'undefined') {
+    object[property] = defaultValue;
+  }
+  return object[property];
+};
+
+/**
+ * Resolves the value for a nested object option.
+ * @template T
+ * @template {keyof T} Property
+ * @template Result
+ * @param {T} object An object.
+ * @param {Property} property A property of the provided object.
+ * @param {function(T | undefined): Result} fn The handler to resolve the property's value.
+ * @returns {Result} The resolved option value.
+ */
+const n = (object, property, fn) => {
+  object[property] = fn(object[property]);
+  return object[property];
+};
+
+module.exports = { d, n };
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/components/CompileErrorTrace.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/components/CompileErrorTrace.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/components/CompileErrorTrace.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,58 @@
+const ansiHTML = require('ansi-html');
+const entities = require('html-entities');
+const theme = require('../theme.js');
+const utils = require('../utils.js');
+
+ansiHTML.setColors(theme);
+
+/**
+ * @typedef {Object} CompileErrorTraceProps
+ * @property {string} errorMessage
+ */
+
+/**
+ * A formatter that turns Webpack compile error messages into highlighted HTML source traces.
+ * @param {Document} document
+ * @param {HTMLElement} root
+ * @param {CompileErrorTraceProps} props
+ * @returns {void}
+ */
+function CompileErrorTrace(document, root, props) {
+  const errorParts = props.errorMessage.split('\n');
+  if (errorParts.length) {
+    if (errorParts[0]) {
+      errorParts[0] = utils.formatFilename(errorParts[0]);
+    }
+
+    const errorMessage = errorParts.splice(1, 1)[0];
+    if (errorMessage) {
+      // Strip filename from the error message
+      errorParts.unshift(errorMessage.replace(/^(.*:)\s.*:(\s.*)$/, '$1$2'));
+    }
+  }
+
+  const stackContainer = document.createElement('pre');
+  stackContainer.innerHTML = entities.decode(
+    ansiHTML(entities.encode(errorParts.join('\n'), { level: 'html5', mode: 'nonAscii' })),
+    { level: 'html5' }
+  );
+  stackContainer.style.fontFamily = [
+    '"Operator Mono SSm"',
+    '"Operator Mono"',
+    '"Fira Code Retina"',
+    '"Fira Code"',
+    '"FiraCode-Retina"',
+    '"Andale Mono"',
+    '"Lucida Console"',
+    'Menlo',
+    'Consolas',
+    'Monaco',
+    'monospace',
+  ].join(', ');
+  stackContainer.style.margin = '0';
+  stackContainer.style.whiteSpace = 'pre-wrap';
+
+  root.appendChild(stackContainer);
+}
+
+module.exports = CompileErrorTrace;
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/components/PageHeader.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/components/PageHeader.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/components/PageHeader.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,58 @@
+const Spacer = require('./Spacer.js');
+const theme = require('../theme.js');
+
+/**
+ * @typedef {Object} PageHeaderProps
+ * @property {string} [message]
+ * @property {string} title
+ * @property {string} [topOffset]
+ */
+
+/**
+ * The header of the overlay.
+ * @param {Document} document
+ * @param {HTMLElement} root
+ * @param {PageHeaderProps} props
+ * @returns {void}
+ */
+function PageHeader(document, root, props) {
+  const pageHeaderContainer = document.createElement('div');
+  pageHeaderContainer.style.background = '#' + theme.dimgrey;
+  pageHeaderContainer.style.boxShadow = '0 1px 4px rgba(0, 0, 0, 0.3)';
+  pageHeaderContainer.style.color = '#' + theme.white;
+  pageHeaderContainer.style.left = '0';
+  pageHeaderContainer.style.right = '0';
+  pageHeaderContainer.style.padding = '1rem 1.5rem';
+  pageHeaderContainer.style.paddingLeft = 'max(1.5rem, env(safe-area-inset-left))';
+  pageHeaderContainer.style.paddingRight = 'max(1.5rem, env(safe-area-inset-right))';
+  pageHeaderContainer.style.position = 'fixed';
+  pageHeaderContainer.style.top = props.topOffset || '0';
+
+  const title = document.createElement('h3');
+  title.innerText = props.title;
+  title.style.color = '#' + theme.red;
+  title.style.fontSize = '1.125rem';
+  title.style.lineHeight = '1.3';
+  title.style.margin = '0';
+  pageHeaderContainer.appendChild(title);
+
+  if (props.message) {
+    title.style.margin = '0 0 0.5rem';
+
+    const message = document.createElement('span');
+    message.innerText = props.message;
+    message.style.color = '#' + theme.white;
+    message.style.wordBreak = 'break-word';
+    pageHeaderContainer.appendChild(message);
+  }
+
+  root.appendChild(pageHeaderContainer);
+
+  // This has to run after appending elements to root
+  // because we need to actual mounted height.
+  Spacer(document, root, {
+    space: pageHeaderContainer.offsetHeight.toString(10),
+  });
+}
+
+module.exports = PageHeader;
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/components/RuntimeErrorFooter.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/components/RuntimeErrorFooter.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/components/RuntimeErrorFooter.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,93 @@
+const Spacer = require('./Spacer.js');
+const theme = require('../theme.js');
+
+/**
+ * @typedef {Object} RuntimeErrorFooterProps
+ * @property {string} [initialFocus]
+ * @property {boolean} multiple
+ * @property {function(MouseEvent): void} onClickCloseButton
+ * @property {function(MouseEvent): void} onClickNextButton
+ * @property {function(MouseEvent): void} onClickPrevButton
+ */
+
+/**
+ * A fixed footer that handles pagination of runtime errors.
+ * @param {Document} document
+ * @param {HTMLElement} root
+ * @param {RuntimeErrorFooterProps} props
+ * @returns {void}
+ */
+function RuntimeErrorFooter(document, root, props) {
+  const footer = document.createElement('div');
+  footer.style.backgroundColor = '#' + theme.dimgrey;
+  footer.style.bottom = '0';
+  footer.style.boxShadow = '0 -1px 4px rgba(0, 0, 0, 0.3)';
+  footer.style.height = '2.5rem';
+  footer.style.left = '0';
+  footer.style.right = '0';
+  footer.style.lineHeight = '2.5rem';
+  footer.style.paddingBottom = '0';
+  footer.style.paddingBottom = 'env(safe-area-inset-bottom)';
+  footer.style.position = 'fixed';
+  footer.style.textAlign = 'center';
+  footer.style.zIndex = '2';
+
+  const BUTTON_CONFIGS = {
+    prev: {
+      id: 'prev',
+      label: '◀&ensp;Prev',
+      onClick: props.onClickPrevButton,
+    },
+    close: {
+      id: 'close',
+      label: '×&ensp;Close',
+      onClick: props.onClickCloseButton,
+    },
+    next: {
+      id: 'next',
+      label: 'Next&ensp;▶',
+      onClick: props.onClickNextButton,
+    },
+  };
+
+  let buttons = [BUTTON_CONFIGS.close];
+  if (props.multiple) {
+    buttons = [BUTTON_CONFIGS.prev, BUTTON_CONFIGS.close, BUTTON_CONFIGS.next];
+  }
+
+  /** @type {HTMLButtonElement | undefined} */
+  let initialFocusButton;
+  for (let i = 0; i < buttons.length; i += 1) {
+    const buttonConfig = buttons[i];
+
+    const button = document.createElement('button');
+    button.id = buttonConfig.id;
+    button.innerHTML = buttonConfig.label;
+    button.tabIndex = 1;
+    button.style.backgroundColor = '#' + theme.dimgrey;
+    button.style.border = 'none';
+    button.style.color = '#' + theme.white;
+    button.style.cursor = 'pointer';
+    button.style.fontSize = 'inherit';
+    button.style.height = '100%';
+    button.style.padding = '0.5rem 0.75rem';
+    button.style.width = (100 / buttons.length).toString(10) + '%';
+    button.addEventListener('click', buttonConfig.onClick);
+
+    if (buttonConfig.id === props.initialFocus) {
+      initialFocusButton = button;
+    }
+
+    footer.appendChild(button);
+  }
+
+  root.appendChild(footer);
+
+  Spacer(document, root, { space: '2.5rem' });
+
+  if (initialFocusButton) {
+    initialFocusButton.focus();
+  }
+}
+
+module.exports = RuntimeErrorFooter;
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/components/RuntimeErrorHeader.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/components/RuntimeErrorHeader.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/components/RuntimeErrorHeader.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,37 @@
+const Spacer = require('./Spacer.js');
+const theme = require('../theme.js');
+
+/**
+ * @typedef {Object} RuntimeErrorHeaderProps
+ * @property {number} currentErrorIndex
+ * @property {number} totalErrors
+ */
+
+/**
+ * A fixed header that shows the total runtime error count.
+ * @param {Document} document
+ * @param {HTMLElement} root
+ * @param {RuntimeErrorHeaderProps} props
+ * @returns {void}
+ */
+function RuntimeErrorHeader(document, root, props) {
+  const header = document.createElement('div');
+  header.innerText = 'Error ' + (props.currentErrorIndex + 1) + ' of ' + props.totalErrors;
+  header.style.backgroundColor = '#' + theme.red;
+  header.style.color = '#' + theme.white;
+  header.style.fontWeight = '500';
+  header.style.height = '2.5rem';
+  header.style.left = '0';
+  header.style.lineHeight = '2.5rem';
+  header.style.position = 'fixed';
+  header.style.textAlign = 'center';
+  header.style.top = '0';
+  header.style.width = '100vw';
+  header.style.zIndex = '2';
+
+  root.appendChild(header);
+
+  Spacer(document, root, { space: '2.5rem' });
+}
+
+module.exports = RuntimeErrorHeader;
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/components/RuntimeErrorStack.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/components/RuntimeErrorStack.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/components/RuntimeErrorStack.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,79 @@
+const ErrorStackParser = require('error-stack-parser');
+const theme = require('../theme.js');
+const utils = require('../utils.js');
+
+/**
+ * @typedef {Object} RuntimeErrorStackProps
+ * @property {Error} error
+ */
+
+/**
+ * A formatter that turns runtime error stacks into highlighted HTML stacks.
+ * @param {Document} document
+ * @param {HTMLElement} root
+ * @param {RuntimeErrorStackProps} props
+ * @returns {void}
+ */
+function RuntimeErrorStack(document, root, props) {
+  const stackTitle = document.createElement('h4');
+  stackTitle.innerText = 'Call Stack';
+  stackTitle.style.color = '#' + theme.white;
+  stackTitle.style.fontSize = '1.0625rem';
+  stackTitle.style.fontWeight = '500';
+  stackTitle.style.lineHeight = '1.3';
+  stackTitle.style.margin = '0 0 0.5rem';
+
+  const stackContainer = document.createElement('div');
+  stackContainer.style.fontSize = '0.8125rem';
+  stackContainer.style.lineHeight = '1.3';
+  stackContainer.style.whiteSpace = 'pre-wrap';
+
+  let errorStacks;
+  try {
+    errorStacks = ErrorStackParser.parse(props.error);
+  } catch (e) {
+    errorStacks = [];
+    stackContainer.innerHTML = 'No stack trace is available for this error!';
+  }
+
+  for (let i = 0; i < Math.min(errorStacks.length, 10); i += 1) {
+    const currentStack = errorStacks[i];
+
+    const functionName = document.createElement('code');
+    functionName.innerHTML = '&emsp;' + currentStack.functionName || '(anonymous function)';
+    functionName.style.color = '#' + theme.yellow;
+    functionName.style.fontFamily = [
+      '"Operator Mono SSm"',
+      '"Operator Mono"',
+      '"Fira Code Retina"',
+      '"Fira Code"',
+      '"FiraCode-Retina"',
+      '"Andale Mono"',
+      '"Lucida Console"',
+      'Menlo',
+      'Consolas',
+      'Monaco',
+      'monospace',
+    ].join(', ');
+
+    const fileName = document.createElement('div');
+    fileName.innerHTML =
+      '&emsp;&emsp;' +
+      utils.formatFilename(currentStack.fileName) +
+      ':' +
+      currentStack.lineNumber +
+      ':' +
+      currentStack.columnNumber;
+    fileName.style.color = '#' + theme.white;
+    fileName.style.fontSize = '0.6875rem';
+    fileName.style.marginBottom = '0.25rem';
+
+    stackContainer.appendChild(functionName);
+    stackContainer.appendChild(fileName);
+  }
+
+  root.appendChild(stackTitle);
+  root.appendChild(stackContainer);
+}
+
+module.exports = RuntimeErrorStack;
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/components/Spacer.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/components/Spacer.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/components/Spacer.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,19 @@
+/**
+ * @typedef {Object} SpacerProps
+ * @property {string} space
+ */
+
+/**
+ * An empty element to add spacing manually.
+ * @param {Document} document
+ * @param {HTMLElement} root
+ * @param {SpacerProps} props
+ * @returns {void}
+ */
+function Spacer(document, root, props) {
+  const spacer = document.createElement('div');
+  spacer.style.paddingBottom = props.space;
+  root.appendChild(spacer);
+}
+
+module.exports = Spacer;
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/containers/CompileErrorContainer.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/containers/CompileErrorContainer.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/containers/CompileErrorContainer.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,25 @@
+const CompileErrorTrace = require('../components/CompileErrorTrace.js');
+const PageHeader = require('../components/PageHeader.js');
+const Spacer = require('../components/Spacer.js');
+
+/**
+ * @typedef {Object} CompileErrorContainerProps
+ * @property {string} errorMessage
+ */
+
+/**
+ * A container to render Webpack compilation error messages with source trace.
+ * @param {Document} document
+ * @param {HTMLElement} root
+ * @param {CompileErrorContainerProps} props
+ * @returns {void}
+ */
+function CompileErrorContainer(document, root, props) {
+  PageHeader(document, root, {
+    title: 'Failed to compile.',
+  });
+  CompileErrorTrace(document, root, { errorMessage: props.errorMessage });
+  Spacer(document, root, { space: '1rem' });
+}
+
+module.exports = CompileErrorContainer;
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/containers/RuntimeErrorContainer.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/containers/RuntimeErrorContainer.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/containers/RuntimeErrorContainer.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,29 @@
+const PageHeader = require('../components/PageHeader.js');
+const RuntimeErrorStack = require('../components/RuntimeErrorStack.js');
+const Spacer = require('../components/Spacer.js');
+
+/**
+ * @typedef {Object} RuntimeErrorContainerProps
+ * @property {Error} currentError
+ */
+
+/**
+ * A container to render runtime error messages with stack trace.
+ * @param {Document} document
+ * @param {HTMLElement} root
+ * @param {RuntimeErrorContainerProps} props
+ * @returns {void}
+ */
+function RuntimeErrorContainer(document, root, props) {
+  PageHeader(document, root, {
+    message: props.currentError.message,
+    title: props.currentError.name,
+    topOffset: '2.5rem',
+  });
+  RuntimeErrorStack(document, root, {
+    error: props.currentError,
+  });
+  Spacer(document, root, { space: '1rem' });
+}
+
+module.exports = RuntimeErrorContainer;
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/index.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,339 @@
+const RuntimeErrorFooter = require('./components/RuntimeErrorFooter.js');
+const RuntimeErrorHeader = require('./components/RuntimeErrorHeader.js');
+const CompileErrorContainer = require('./containers/CompileErrorContainer.js');
+const RuntimeErrorContainer = require('./containers/RuntimeErrorContainer.js');
+const theme = require('./theme.js');
+const utils = require('./utils.js');
+
+/**
+ * @callback RenderFn
+ * @returns {void}
+ */
+
+/* ===== Cached elements for DOM manipulations ===== */
+/**
+ * The iframe that contains the overlay.
+ * @type {HTMLIFrameElement}
+ */
+let iframeRoot = null;
+/**
+ * The document object from the iframe root, used to create and render elements.
+ * @type {Document}
+ */
+let rootDocument = null;
+/**
+ * The root div elements will attach to.
+ * @type {HTMLDivElement}
+ */
+let root = null;
+/**
+ * A Cached function to allow deferred render.
+ * @type {RenderFn | null}
+ */
+let scheduledRenderFn = null;
+
+/* ===== Overlay State ===== */
+/**
+ * The latest error message from Webpack compilation.
+ * @type {string}
+ */
+let currentCompileErrorMessage = '';
+/**
+ * Index of the error currently shown by the overlay.
+ * @type {number}
+ */
+let currentRuntimeErrorIndex = 0;
+/**
+ * The latest runtime error objects.
+ * @type {Error[]}
+ */
+let currentRuntimeErrors = [];
+/**
+ * The render mode the overlay is currently in.
+ * @type {'compileError' | 'runtimeError' | null}
+ */
+let currentMode = null;
+
+/**
+ * @typedef {Object} IframeProps
+ * @property {function(): void} onIframeLoad
+ */
+
+/**
+ * Creates the main `iframe` the overlay will attach to.
+ * Accepts a callback to be ran after iframe is initialized.
+ * @param {Document} document
+ * @param {HTMLElement} root
+ * @param {IframeProps} props
+ * @returns {HTMLIFrameElement}
+ */
+function IframeRoot(document, root, props) {
+  const iframe = document.createElement('iframe');
+  iframe.id = 'react-refresh-overlay';
+  iframe.src = 'about:blank';
+
+  iframe.style.border = 'none';
+  iframe.style.height = '100%';
+  iframe.style.left = '0';
+  iframe.style.minHeight = '100vh';
+  iframe.style.minHeight = '-webkit-fill-available';
+  iframe.style.position = 'fixed';
+  iframe.style.top = '0';
+  iframe.style.width = '100vw';
+  iframe.style.zIndex = '2147483647';
+  iframe.addEventListener('load', function onLoad() {
+    // Reset margin of iframe body
+    iframe.contentDocument.body.style.margin = '0';
+    props.onIframeLoad();
+  });
+
+  // We skip mounting and returns as we need to ensure
+  // the load event is fired after we setup the global variable
+  return iframe;
+}
+
+/**
+ * Creates the main `div` element for the overlay to render.
+ * @param {Document} document
+ * @param {HTMLElement} root
+ * @returns {HTMLDivElement}
+ */
+function OverlayRoot(document, root) {
+  const div = document.createElement('div');
+  div.id = 'react-refresh-overlay-error';
+
+  // Style the contents container
+  div.style.backgroundColor = '#' + theme.grey;
+  div.style.boxSizing = 'border-box';
+  div.style.color = '#' + theme.white;
+  div.style.fontFamily = [
+    '-apple-system',
+    'BlinkMacSystemFont',
+    '"Segoe UI"',
+    '"Helvetica Neue"',
+    'Helvetica',
+    'Arial',
+    'sans-serif',
+    '"Apple Color Emoji"',
+    '"Segoe UI Emoji"',
+    'Segoe UI Symbol',
+  ].join(', ');
+  div.style.fontSize = '0.875rem';
+  div.style.height = '100%';
+  div.style.lineHeight = '1.3';
+  div.style.overflow = 'auto';
+  div.style.padding = '1rem 1.5rem 0';
+  div.style.paddingTop = 'max(1rem, env(safe-area-inset-top))';
+  div.style.paddingRight = 'max(1.5rem, env(safe-area-inset-right))';
+  div.style.paddingBottom = 'env(safe-area-inset-bottom)';
+  div.style.paddingLeft = 'max(1.5rem, env(safe-area-inset-left))';
+  div.style.width = '100vw';
+
+  root.appendChild(div);
+  return div;
+}
+
+/**
+ * Ensures the iframe root and the overlay root are both initialized before render.
+ * If check fails, render will be deferred until both roots are initialized.
+ * @param {RenderFn} renderFn A function that triggers a DOM render.
+ * @returns {void}
+ */
+function ensureRootExists(renderFn) {
+  if (root) {
+    // Overlay root is ready, we can render right away.
+    renderFn();
+    return;
+  }
+
+  // Creating an iframe may be asynchronous so we'll defer render.
+  // In case of multiple calls, function from the last call will be used.
+  scheduledRenderFn = renderFn;
+
+  if (iframeRoot) {
+    // Iframe is already ready, it will fire the load event.
+    return;
+  }
+
+  // Create the iframe root, and, the overlay root inside it when it is ready.
+  iframeRoot = IframeRoot(document, document.body, {
+    onIframeLoad: function onIframeLoad() {
+      rootDocument = iframeRoot.contentDocument;
+      root = OverlayRoot(rootDocument, rootDocument.body);
+      scheduledRenderFn();
+    },
+  });
+
+  // We have to mount here to ensure `iframeRoot` is set when `onIframeLoad` fires.
+  // This is because onIframeLoad() will be called synchronously
+  // or asynchronously depending on the browser.
+  document.body.appendChild(iframeRoot);
+}
+
+/**
+ * Creates the main `div` element for the overlay to render.
+ * @returns {void}
+ */
+function render() {
+  ensureRootExists(function () {
+    const currentFocus = rootDocument.activeElement;
+    let currentFocusId;
+    if (currentFocus.localName === 'button' && currentFocus.id) {
+      currentFocusId = currentFocus.id;
+    }
+
+    utils.removeAllChildren(root);
+
+    if (currentCompileErrorMessage) {
+      currentMode = 'compileError';
+
+      CompileErrorContainer(rootDocument, root, {
+        errorMessage: currentCompileErrorMessage,
+      });
+    } else if (currentRuntimeErrors.length) {
+      currentMode = 'runtimeError';
+
+      RuntimeErrorHeader(rootDocument, root, {
+        currentErrorIndex: currentRuntimeErrorIndex,
+        totalErrors: currentRuntimeErrors.length,
+      });
+      RuntimeErrorContainer(rootDocument, root, {
+        currentError: currentRuntimeErrors[currentRuntimeErrorIndex],
+      });
+      RuntimeErrorFooter(rootDocument, root, {
+        initialFocus: currentFocusId,
+        multiple: currentRuntimeErrors.length > 1,
+        onClickCloseButton: function onClose() {
+          clearRuntimeErrors();
+        },
+        onClickNextButton: function onNext() {
+          if (currentRuntimeErrorIndex === currentRuntimeErrors.length - 1) {
+            return;
+          }
+          currentRuntimeErrorIndex += 1;
+          ensureRootExists(render);
+        },
+        onClickPrevButton: function onPrev() {
+          if (currentRuntimeErrorIndex === 0) {
+            return;
+          }
+          currentRuntimeErrorIndex -= 1;
+          ensureRootExists(render);
+        },
+      });
+    }
+  });
+}
+
+/**
+ * Destroys the state of the overlay.
+ * @returns {void}
+ */
+function cleanup() {
+  // Clean up and reset all internal state.
+  document.body.removeChild(iframeRoot);
+  scheduledRenderFn = null;
+  root = null;
+  iframeRoot = null;
+}
+
+/**
+ * Clears Webpack compilation errors and dismisses the compile error overlay.
+ * @returns {void}
+ */
+function clearCompileError() {
+  if (!root || currentMode !== 'compileError') {
+    return;
+  }
+
+  currentCompileErrorMessage = '';
+  currentMode = null;
+  cleanup();
+}
+
+/**
+ * Clears runtime error records and dismisses the runtime error overlay.
+ * @param {boolean} [dismissOverlay] Whether to dismiss the overlay or not.
+ * @returns {void}
+ */
+function clearRuntimeErrors(dismissOverlay) {
+  if (!root || currentMode !== 'runtimeError') {
+    return;
+  }
+
+  currentRuntimeErrorIndex = 0;
+  currentRuntimeErrors = [];
+
+  if (typeof dismissOverlay === 'undefined' || dismissOverlay) {
+    currentMode = null;
+    cleanup();
+  }
+}
+
+/**
+ * Shows the compile error overlay with the specific Webpack error message.
+ * @param {string} message
+ * @returns {void}
+ */
+function showCompileError(message) {
+  if (!message) {
+    return;
+  }
+
+  currentCompileErrorMessage = message;
+
+  render();
+}
+
+/**
+ * Shows the runtime error overlay with the specific error records.
+ * @param {Error[]} errors
+ * @returns {void}
+ */
+function showRuntimeErrors(errors) {
+  if (!errors || !errors.length) {
+    return;
+  }
+
+  currentRuntimeErrors = errors;
+
+  render();
+}
+
+/**
+ * The debounced version of `showRuntimeErrors` to prevent frequent renders
+ * due to rapid firing listeners.
+ * @param {Error[]} errors
+ * @returns {void}
+ */
+const debouncedShowRuntimeErrors = utils.debounce(showRuntimeErrors, 30);
+
+/**
+ * Detects if an error is a Webpack compilation error.
+ * @param {Error} error The error of interest.
+ * @returns {boolean} If the error is a Webpack compilation error.
+ */
+function isWebpackCompileError(error) {
+  return /Module [A-z ]+\(from/.test(error.message) || /Cannot find module/.test(error.message);
+}
+
+/**
+ * Handles runtime error contexts captured with EventListeners.
+ * Integrates with a runtime error overlay.
+ * @param {Error} error A valid error object.
+ * @returns {void}
+ */
+function handleRuntimeError(error) {
+  if (error && !isWebpackCompileError(error) && currentRuntimeErrors.indexOf(error) === -1) {
+    currentRuntimeErrors = currentRuntimeErrors.concat(error);
+  }
+  debouncedShowRuntimeErrors(currentRuntimeErrors);
+}
+
+module.exports = Object.freeze({
+  clearCompileError: clearCompileError,
+  clearRuntimeErrors: clearRuntimeErrors,
+  handleRuntimeError: handleRuntimeError,
+  showCompileError: showCompileError,
+  showRuntimeErrors: showRuntimeErrors,
+});
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/package.json
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+{
+  "type": "commonjs"
+}
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/theme.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/theme.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/theme.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,39 @@
+/**
+ * @typedef {Object} Theme
+ * @property {string[]} reset
+ * @property {string} black
+ * @property {string} red
+ * @property {string} green
+ * @property {string} yellow
+ * @property {string} blue
+ * @property {string} magenta
+ * @property {string} cyan
+ * @property {string} white
+ * @property {string} lightgrey
+ * @property {string} darkgrey
+ * @property {string} grey
+ * @property {string} dimgrey
+ */
+
+/**
+ * @type {Theme} theme
+ * A collection of colors to be used by the overlay.
+ * Partially adopted from Tomorrow Night Bright.
+ */
+const theme = {
+  reset: ['transparent', 'transparent'],
+  black: '000000',
+  red: 'D34F56',
+  green: 'B9C954',
+  yellow: 'E6C452',
+  blue: '7CA7D8',
+  magenta: 'C299D6',
+  cyan: '73BFB1',
+  white: 'FFFFFF',
+  lightgrey: 'C7C7C7',
+  darkgrey: 'A9A9A9',
+  grey: '474747',
+  dimgrey: '343434',
+};
+
+module.exports = theme;
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/utils.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/utils.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/overlay/utils.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,74 @@
+/**
+ * Debounce a function to delay invoking until wait (ms) have elapsed since the last invocation.
+ * @param {function(...*): *} fn The function to be debounced.
+ * @param {number} wait Milliseconds to wait before invoking again.
+ * @return {function(...*): void} The debounced function.
+ */
+function debounce(fn, wait) {
+  /**
+   * A cached setTimeout handler.
+   * @type {number | undefined}
+   */
+  let timer;
+
+  /**
+   * @returns {void}
+   */
+  function debounced() {
+    const context = this;
+    const args = arguments;
+
+    clearTimeout(timer);
+    timer = setTimeout(function () {
+      return fn.apply(context, args);
+    }, wait);
+  }
+
+  return debounced;
+}
+
+/**
+ * Prettify a filename from error stacks into the desired format.
+ * @param {string} filename The filename to be formatted.
+ * @returns {string} The formatted filename.
+ */
+function formatFilename(filename) {
+  // Strip away protocol and domain for compiled files
+  const htmlMatch = /^https?:\/\/(.*)\/(.*)/.exec(filename);
+  if (htmlMatch && htmlMatch[1] && htmlMatch[2]) {
+    return htmlMatch[2];
+  }
+
+  // Strip everything before the first directory for source files
+  const sourceMatch = /\/.*?([^./]+[/|\\].*)$/.exec(filename);
+  if (sourceMatch && sourceMatch[1]) {
+    return sourceMatch[1].replace(/\?$/, '');
+  }
+
+  // Unknown filename type, use it as is
+  return filename;
+}
+
+/**
+ * Remove all children of an element.
+ * @param {HTMLElement} element A valid HTML element.
+ * @param {number} [skip] Number of elements to skip removing.
+ * @returns {void}
+ */
+function removeAllChildren(element, skip) {
+  /** @type {Node[]} */
+  const childList = Array.prototype.slice.call(
+    element.childNodes,
+    typeof skip !== 'undefined' ? skip : 0
+  );
+
+  for (let i = 0; i < childList.length; i += 1) {
+    element.removeChild(childList[i]);
+  }
+}
+
+module.exports = {
+  debounce: debounce,
+  formatFilename: formatFilename,
+  removeAllChildren: removeAllChildren,
+};
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/package.json
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,147 @@
+{
+  "name": "@pmmmwh/react-refresh-webpack-plugin",
+  "version": "0.5.17",
+  "description": "An **EXPERIMENTAL** Webpack plugin to enable \"Fast Refresh\" (also previously known as _Hot Reloading_) for React components.",
+  "keywords": [
+    "react",
+    "javascript",
+    "webpack",
+    "refresh",
+    "hmr",
+    "hotreload",
+    "livereload",
+    "live",
+    "edit",
+    "hot",
+    "reload"
+  ],
+  "homepage": "https://github.com/pmmmwh/react-refresh-webpack-plugin#readme",
+  "bugs": {
+    "url": "https://github.com/pmmmwh/react-refresh-webpack-plugin/issues"
+  },
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/pmmmwh/react-refresh-webpack-plugin.git"
+  },
+  "license": "MIT",
+  "author": "Michael Mok",
+  "main": "lib/index.js",
+  "types": "types/lib/index.d.ts",
+  "files": [
+    "client",
+    "lib",
+    "loader",
+    "options",
+    "overlay",
+    "sockets",
+    "types"
+  ],
+  "scripts": {
+    "test": "run-s -c test:pre \"test:exec {@}\" test:post --",
+    "test:webpack-4": "cross-env WEBPACK_VERSION=4 yarn test",
+    "test:pre": "yarn add -D file:./",
+    "test:exec": "node scripts/test.js",
+    "test:post": "yarn remove @pmmmwh/react-refresh-webpack-plugin",
+    "lint": "eslint --report-unused-disable-directives --ext .js,.jsx .",
+    "lint:fix": "yarn lint --fix",
+    "format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,md}\"",
+    "format:check": "prettier --check \"**/*.{js,jsx,ts,tsx,json,md}\"",
+    "types:clean": "rimraf types",
+    "types:compile": "tsc -p tsconfig.json",
+    "types:prune-private": "del \"types/*/*\" \"!types/{lib,loader,options}/{index,types}.d.ts\"",
+    "generate-types": "run-s types:clean types:compile types:prune-private \"format --loglevel silent\"",
+    "prepublishOnly": "yarn generate-types"
+  },
+  "dependencies": {
+    "ansi-html": "^0.0.9",
+    "core-js-pure": "^3.23.3",
+    "error-stack-parser": "^2.0.6",
+    "html-entities": "^2.1.0",
+    "loader-utils": "^2.0.4",
+    "schema-utils": "^4.2.0",
+    "source-map": "^0.7.3"
+  },
+  "devDependencies": {
+    "@babel/core": "^7.14.2",
+    "@babel/plugin-transform-modules-commonjs": "^7.14.0",
+    "@types/cross-spawn": "^6.0.2",
+    "@types/fs-extra": "^11.0.4",
+    "@types/jest": "^29.5.12",
+    "@types/json-schema": "^7.0.6",
+    "@types/module-alias": "^2.0.0",
+    "@types/node": "^20.5.0",
+    "@types/semver": "^7.3.9",
+    "@types/webpack": "^5.28.0",
+    "babel-loader": "^8.1.0",
+    "cross-env": "^7.0.3",
+    "cross-spawn": "^7.0.5",
+    "del-cli": "^5.1.0",
+    "eslint": "^8.6.0",
+    "eslint-config-prettier": "^9.0.0",
+    "eslint-plugin-prettier": "^5.0.0",
+    "fs-extra": "^11.2.0",
+    "get-port": "^5.1.1",
+    "jest": "^29.7.0",
+    "jest-environment-jsdom": "^29.7.0",
+    "jest-environment-node": "^29.7.0",
+    "jest-junit": "^16.0.0",
+    "jest-location-mock": "^2.0.0",
+    "module-alias": "^2.2.2",
+    "nanoid": "^3.3.8",
+    "npm-run-all": "^4.1.5",
+    "prettier": "^3.3.0",
+    "puppeteer": "^22.10.0",
+    "react-refresh": "^0.14.0",
+    "semver": "^7.5.2",
+    "sourcemap-validator": "^2.1.0",
+    "type-fest": "^4.0.0",
+    "typescript": "~5.4.5",
+    "webpack": "^5.94.0",
+    "webpack-cli": "^5.1.4",
+    "webpack-cli-v4": "npm:webpack-cli@4.x",
+    "webpack-dev-server": "^5.0.4",
+    "webpack-dev-server-v3": "npm:webpack-dev-server@3.x",
+    "webpack-dev-server-v4": "npm:webpack-dev-server@4.x",
+    "webpack-hot-middleware": "^2.25.0",
+    "webpack-plugin-serve": "^1.4.1",
+    "webpack-v4": "npm:webpack@4.x",
+    "yn": "^4.0.0"
+  },
+  "peerDependencies": {
+    "@types/webpack": "4.x || 5.x",
+    "react-refresh": ">=0.10.0 <1.0.0",
+    "sockjs-client": "^1.4.0",
+    "type-fest": ">=0.17.0 <5.0.0",
+    "webpack": ">=4.43.0 <6.0.0",
+    "webpack-dev-server": "3.x || 4.x || 5.x",
+    "webpack-hot-middleware": "2.x",
+    "webpack-plugin-serve": "0.x || 1.x"
+  },
+  "peerDependenciesMeta": {
+    "@types/webpack": {
+      "optional": true
+    },
+    "sockjs-client": {
+      "optional": true
+    },
+    "type-fest": {
+      "optional": true
+    },
+    "webpack-dev-server": {
+      "optional": true
+    },
+    "webpack-hot-middleware": {
+      "optional": true
+    },
+    "webpack-plugin-serve": {
+      "optional": true
+    }
+  },
+  "resolutions": {
+    "type-fest": "^4.0.0"
+  },
+  "engines": {
+    "node": ">= 10.13"
+  },
+  "packageManager": "yarn@1.22.22+sha1.ac34549e6aa8e7ead463a7407e1c7390f61a6610"
+}
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/sockets/WDSSocket.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/sockets/WDSSocket.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/sockets/WDSSocket.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,32 @@
+/* global __webpack_dev_server_client__ */
+
+const getSocketUrlParts = require('./utils/getSocketUrlParts.js');
+const getUrlFromParts = require('./utils/getUrlFromParts');
+const getWDSMetadata = require('./utils/getWDSMetadata');
+
+/**
+ * Initializes a socket server for HMR for webpack-dev-server.
+ * @param {function(*): void} messageHandler A handler to consume Webpack compilation messages.
+ * @param {string} [resourceQuery] Webpack's `__resourceQuery` string.
+ * @returns {void}
+ */
+function initWDSSocket(messageHandler, resourceQuery) {
+  if (typeof __webpack_dev_server_client__ !== 'undefined') {
+    let SocketClient = __webpack_dev_server_client__;
+    if (typeof __webpack_dev_server_client__.default !== 'undefined') {
+      SocketClient = __webpack_dev_server_client__.default;
+    }
+
+    const wdsMeta = getWDSMetadata(SocketClient);
+    const urlParts = getSocketUrlParts(resourceQuery, wdsMeta);
+
+    const connection = new SocketClient(getUrlFromParts(urlParts, wdsMeta));
+
+    connection.onMessage(function onSocketMessage(data) {
+      const message = JSON.parse(data);
+      messageHandler(message);
+    });
+  }
+}
+
+module.exports = { init: initWDSSocket };
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/sockets/WHMEventSource.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/sockets/WHMEventSource.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/sockets/WHMEventSource.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,31 @@
+/**
+ * The hard-coded singleton key for webpack-hot-middleware's client instance.
+ *
+ * [Ref](https://github.com/webpack-contrib/webpack-hot-middleware/blob/cb29abb9dde435a1ac8e9b19f82d7d36b1093198/client.js#L152)
+ */
+const singletonKey = '__webpack_hot_middleware_reporter__';
+
+/**
+ * Initializes a socket server for HMR for webpack-hot-middleware.
+ * @param {function(*): void} messageHandler A handler to consume Webpack compilation messages.
+ * @returns {void}
+ */
+function initWHMEventSource(messageHandler) {
+  const client = window[singletonKey];
+
+  client.useCustomOverlay({
+    showProblems: function showProblems(type, data) {
+      const error = {
+        data: data,
+        type: type,
+      };
+
+      messageHandler(error);
+    },
+    clear: function clear() {
+      messageHandler({ type: 'ok' });
+    },
+  });
+}
+
+module.exports = { init: initWHMEventSource };
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/sockets/WPSSocket.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/sockets/WPSSocket.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/sockets/WPSSocket.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,51 @@
+/* global ʎɐɹɔosǝʌɹǝs */
+const { ClientSocket } = require('webpack-plugin-serve/lib/client/ClientSocket');
+
+/**
+ * Initializes a socket server for HMR for webpack-plugin-serve.
+ * @param {function(*): void} messageHandler A handler to consume Webpack compilation messages.
+ * @returns {void}
+ */
+function initWPSSocket(messageHandler) {
+  /**
+   * The hard-coded options injection key from webpack-plugin-serve.
+   *
+   * [Ref](https://github.com/shellscape/webpack-plugin-serve/blob/aeb49f14e900802c98df4a4607a76bc67b1cffdf/lib/index.js#L258)
+   * @type {Object | undefined}
+   */
+  let options;
+  try {
+    options = ʎɐɹɔosǝʌɹǝs;
+  } catch (e) {
+    // Bail out because this indicates the plugin is not included
+    return;
+  }
+
+  const { address, client = {}, secure } = options;
+  const protocol = secure ? 'wss' : 'ws';
+  const socket = new ClientSocket(client, protocol + '://' + (client.address || address) + '/wps');
+
+  socket.addEventListener('message', function listener(message) {
+    const { action, data } = JSON.parse(message.data);
+
+    switch (action) {
+      case 'done': {
+        messageHandler({ type: 'ok' });
+        break;
+      }
+      case 'problems': {
+        if (data.errors.length) {
+          messageHandler({ type: 'errors', data: data.errors });
+        } else if (data.warnings.length) {
+          messageHandler({ type: 'warnings', data: data.warnings });
+        }
+        break;
+      }
+      default: {
+        // Do nothing
+      }
+    }
+  });
+}
+
+module.exports = { init: initWPSSocket };
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/sockets/package.json
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/sockets/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/sockets/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+{
+  "type": "commonjs"
+}
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/sockets/utils/getCurrentScriptSource.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/sockets/utils/getCurrentScriptSource.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/sockets/utils/getCurrentScriptSource.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,30 @@
+/**
+ * Gets the source (i.e. host) of the script currently running.
+ * @returns {string}
+ */
+function getCurrentScriptSource() {
+  // `document.currentScript` is the most accurate way to get the current running script,
+  // but is not supported in all browsers (most notably, IE).
+  if ('currentScript' in document) {
+    // In some cases, `document.currentScript` would be `null` even if the browser supports it:
+    // e.g. asynchronous chunks on Firefox.
+    // We should not fallback to the list-approach as it would not be safe.
+    if (document.currentScript == null) return;
+    return document.currentScript.getAttribute('src');
+  }
+  // Fallback to getting all scripts running in the document,
+  // and finding the last one injected.
+  else {
+    const scriptElementsWithSrc = Array.prototype.filter.call(
+      document.scripts || [],
+      function (elem) {
+        return elem.getAttribute('src');
+      }
+    );
+    if (!scriptElementsWithSrc.length) return;
+    const currentScript = scriptElementsWithSrc[scriptElementsWithSrc.length - 1];
+    return currentScript.getAttribute('src');
+  }
+}
+
+module.exports = getCurrentScriptSource;
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/sockets/utils/getSocketUrlParts.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/sockets/utils/getSocketUrlParts.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/sockets/utils/getSocketUrlParts.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,141 @@
+const getCurrentScriptSource = require('./getCurrentScriptSource.js');
+
+/**
+ * @typedef {Object} SocketUrlParts
+ * @property {string} [auth]
+ * @property {string} hostname
+ * @property {string} [protocol]
+ * @property {string} pathname
+ * @property {string} [port]
+ */
+
+/**
+ * Parse current location and Webpack's `__resourceQuery` into parts that can create a valid socket URL.
+ * @param {string} [resourceQuery] The Webpack `__resourceQuery` string.
+ * @param {import('./getWDSMetadata').WDSMetaObj} [metadata] The parsed WDS metadata object.
+ * @returns {SocketUrlParts} The parsed URL parts.
+ * @see https://webpack.js.org/api/module-variables/#__resourcequery-webpack-specific
+ */
+function getSocketUrlParts(resourceQuery, metadata) {
+  if (typeof metadata === 'undefined') {
+    metadata = {};
+  }
+
+  /** @type {SocketUrlParts} */
+  let urlParts = {};
+
+  // If the resource query is available,
+  // parse it and ignore everything we received from the script host.
+  if (resourceQuery) {
+    const parsedQuery = {};
+    const searchParams = new URLSearchParams(resourceQuery.slice(1));
+    searchParams.forEach(function (value, key) {
+      parsedQuery[key] = value;
+    });
+
+    urlParts.hostname = parsedQuery.sockHost;
+    urlParts.pathname = parsedQuery.sockPath;
+    urlParts.port = parsedQuery.sockPort;
+
+    // Make sure the protocol from resource query has a trailing colon
+    if (parsedQuery.sockProtocol) {
+      urlParts.protocol = parsedQuery.sockProtocol + ':';
+    }
+  } else {
+    const scriptSource = getCurrentScriptSource();
+
+    let url = {};
+    try {
+      // The placeholder `baseURL` with `window.location.href`,
+      // is to allow parsing of path-relative or protocol-relative URLs,
+      // and will have no effect if `scriptSource` is a fully valid URL.
+      url = new URL(scriptSource, window.location.href);
+    } catch (e) {
+      // URL parsing failed, do nothing.
+      // We will still proceed to see if we can recover using `resourceQuery`
+    }
+
+    // Parse authentication credentials in case we need them
+    if (url.username) {
+      // Since HTTP basic authentication does not allow empty username,
+      // we only include password if the username is not empty.
+      // Result: <username> or <username>:<password>
+      urlParts.auth = url.username;
+      if (url.password) {
+        urlParts.auth += ':' + url.password;
+      }
+    }
+
+    // `file://` URLs has `'null'` origin
+    if (url.origin !== 'null') {
+      urlParts.hostname = url.hostname;
+    }
+
+    urlParts.protocol = url.protocol;
+    urlParts.port = url.port;
+  }
+
+  if (!urlParts.pathname) {
+    if (metadata.version === 4) {
+      // This is hard-coded in WDS v4
+      urlParts.pathname = '/ws';
+    } else {
+      // This is hard-coded in WDS v3
+      urlParts.pathname = '/sockjs-node';
+    }
+  }
+
+  // Check for IPv4 and IPv6 host addresses that correspond to any/empty.
+  // This is important because `hostname` can be empty for some hosts,
+  // such as 'about:blank' or 'file://' URLs.
+  const isEmptyHostname =
+    urlParts.hostname === '0.0.0.0' || urlParts.hostname === '[::]' || !urlParts.hostname;
+  // We only re-assign the hostname if it is empty,
+  // and if we are using HTTP/HTTPS protocols.
+  if (
+    isEmptyHostname &&
+    window.location.hostname &&
+    window.location.protocol.indexOf('http') === 0
+  ) {
+    urlParts.hostname = window.location.hostname;
+  }
+
+  // We only re-assign `protocol` when `protocol` is unavailable,
+  // or if `hostname` is available and is empty,
+  // since otherwise we risk creating an invalid URL.
+  // We also do this when no sockProtocol was passed to the config and 'https' is used,
+  // as it mandates the use of secure sockets.
+  if (
+    !urlParts.protocol ||
+    (urlParts.hostname &&
+      (isEmptyHostname || (!resourceQuery && window.location.protocol === 'https:')))
+  ) {
+    urlParts.protocol = window.location.protocol;
+  }
+
+  // We only re-assign port when it is not available
+  if (!urlParts.port) {
+    urlParts.port = window.location.port;
+  }
+
+  if (!urlParts.hostname || !urlParts.pathname) {
+    throw new Error(
+      [
+        '[React Refresh] Failed to get an URL for the socket connection.',
+        "This usually means that the current executed script doesn't have a `src` attribute set.",
+        'You should either specify the socket path parameters under the `devServer` key in your Webpack config, or use the `overlay` option.',
+        'https://github.com/pmmmwh/react-refresh-webpack-plugin/blob/main/docs/API.md#overlay',
+      ].join('\n')
+    );
+  }
+
+  return {
+    auth: urlParts.auth,
+    hostname: urlParts.hostname,
+    pathname: urlParts.pathname,
+    protocol: urlParts.protocol,
+    port: urlParts.port || undefined,
+  };
+}
+
+module.exports = getSocketUrlParts;
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/sockets/utils/getUrlFromParts.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/sockets/utils/getUrlFromParts.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/sockets/utils/getUrlFromParts.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,35 @@
+/**
+ * Create a valid URL from parsed URL parts.
+ * @param {import('./getSocketUrlParts').SocketUrlParts} urlParts The parsed URL parts.
+ * @param {import('./getWDSMetadata').WDSMetaObj} [metadata] The parsed WDS metadata object.
+ * @returns {string} The generated URL.
+ */
+function urlFromParts(urlParts, metadata) {
+  if (typeof metadata === 'undefined') {
+    metadata = {};
+  }
+
+  let fullProtocol = 'http:';
+  if (urlParts.protocol) {
+    fullProtocol = urlParts.protocol;
+  }
+  if (metadata.enforceWs) {
+    fullProtocol = fullProtocol.replace(/^(?:http|.+-extension|file)/i, 'ws');
+  }
+
+  fullProtocol = fullProtocol + '//';
+
+  let fullHost = urlParts.hostname;
+  if (urlParts.auth) {
+    const fullAuth = urlParts.auth.split(':').map(encodeURIComponent).join(':') + '@';
+    fullHost = fullAuth + fullHost;
+  }
+  if (urlParts.port) {
+    fullHost = fullHost + ':' + urlParts.port;
+  }
+
+  const url = new URL(urlParts.pathname, fullProtocol + fullHost);
+  return url.href;
+}
+
+module.exports = urlFromParts;
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/sockets/utils/getWDSMetadata.js
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/sockets/utils/getWDSMetadata.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/sockets/utils/getWDSMetadata.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,44 @@
+/**
+ * @typedef {Object} WDSMetaObj
+ * @property {boolean} enforceWs
+ * @property {number} version
+ */
+
+/**
+ * Derives WDS metadata from a compatible socket client.
+ * @param {Function} SocketClient A WDS socket client (SockJS/WebSocket).
+ * @returns {WDSMetaObj} The parsed WDS metadata object.
+ */
+function getWDSMetadata(SocketClient) {
+  let enforceWs = false;
+  if (
+    typeof SocketClient.name !== 'undefined' &&
+    SocketClient.name !== null &&
+    SocketClient.name.toLowerCase().includes('websocket')
+  ) {
+    enforceWs = true;
+  }
+
+  let version;
+  // WDS versions <=3.5.0
+  if (!('onMessage' in SocketClient.prototype)) {
+    version = 3;
+  } else {
+    // WDS versions >=3.5.0 <4
+    if (
+      'getClientPath' in SocketClient ||
+      Object.getPrototypeOf(SocketClient).name === 'BaseClient'
+    ) {
+      version = 3;
+    } else {
+      version = 4;
+    }
+  }
+
+  return {
+    enforceWs: enforceWs,
+    version: version,
+  };
+}
+
+module.exports = getWDSMetadata;
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/types/lib/index.d.ts
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/types/lib/index.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/types/lib/index.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,21 @@
+export = ReactRefreshPlugin;
+declare class ReactRefreshPlugin {
+  /**
+   * @param {import('./types').ReactRefreshPluginOptions} [options] Options for react-refresh-plugin.
+   */
+  constructor(options?: import('./types').ReactRefreshPluginOptions | undefined);
+  /**
+   * @readonly
+   * @type {import('./types').NormalizedPluginOptions}
+   */
+  readonly options: import('./types').NormalizedPluginOptions;
+  /**
+   * Applies the plugin.
+   * @param {import('webpack').Compiler} compiler A webpack compiler object.
+   * @returns {void}
+   */
+  apply(compiler: import('webpack').Compiler): void;
+}
+declare namespace ReactRefreshPlugin {
+  export { ReactRefreshPlugin };
+}
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/types/lib/types.d.ts
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/types/lib/types.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/types/lib/types.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,77 @@
+export type ErrorOverlayOptions = {
+  /**
+   * Path to a JS file that sets up the error overlay integration.
+   */
+  entry?: string | false | undefined;
+  /**
+   * The error overlay module to use.
+   */
+  module?: string | false | undefined;
+  /**
+   * The socket host to use (WDS only).
+   */
+  sockHost?: string | undefined;
+  /**
+   * Path to a JS file that sets up the Webpack socket integration.
+   */
+  sockIntegration?:
+    | import('type-fest').LiteralUnion<false | 'wds' | 'whm' | 'wps', string>
+    | undefined;
+  /**
+   * The socket path to use (WDS only).
+   */
+  sockPath?: string | undefined;
+  /**
+   * The socket port to use (WDS only).
+   */
+  sockPort?: number | undefined;
+  /**
+   * The socket protocol to use (WDS only).
+   */
+  sockProtocol?: 'http' | 'https' | 'ws' | 'wss' | undefined;
+  /**
+   * Uses a polyfill for the DOM URL API (WDS only).
+   */
+  useURLPolyfill?: boolean | undefined;
+};
+export type NormalizedErrorOverlayOptions = import('type-fest').SetRequired<
+  ErrorOverlayOptions,
+  'entry' | 'module' | 'sockIntegration'
+>;
+export type ReactRefreshPluginOptions = {
+  /**
+   * Enables strict ES Modules compatible runtime.
+   */
+  esModule?: boolean | import('../loader/types').ESModuleOptions | undefined;
+  /**
+   * Files to explicitly exclude from processing.
+   */
+  exclude?: string | RegExp | (string | RegExp)[] | undefined;
+  /**
+   * Enables the plugin forcefully.
+   */
+  forceEnable?: boolean | undefined;
+  /**
+   * Files to explicitly include for processing.
+   */
+  include?: string | RegExp | (string | RegExp)[] | undefined;
+  /**
+   * Name of the library bundle.
+   */
+  library?: string | undefined;
+  /**
+   * Modifies how the error overlay integration works in the plugin.
+   */
+  overlay?: boolean | ErrorOverlayOptions | undefined;
+};
+export type OverlayOverrides = {
+  /**
+   * Modifies how the error overlay integration works in the plugin.
+   */
+  overlay: false | NormalizedErrorOverlayOptions;
+};
+export type NormalizedPluginOptions = import('type-fest').SetRequired<
+  import('type-fest').Except<ReactRefreshPluginOptions, 'overlay'>,
+  'exclude' | 'include'
+> &
+  OverlayOverrides;
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/types/loader/index.d.ts
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/types/loader/index.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/types/loader/index.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,17 @@
+export = ReactRefreshLoader;
+/**
+ * A simple Webpack loader to inject react-refresh HMR code into modules.
+ *
+ * [Reference for Loader API](https://webpack.js.org/api/loaders/)
+ * @this {import('webpack').LoaderContext<import('./types').ReactRefreshLoaderOptions>}
+ * @param {string} source The original module source code.
+ * @param {import('source-map').RawSourceMap} [inputSourceMap] The source map of the module.
+ * @param {*} [meta] The loader metadata passed in.
+ * @returns {void}
+ */
+declare function ReactRefreshLoader(
+  this: import('webpack').LoaderContext<import('./types').ReactRefreshLoaderOptions>,
+  source: string,
+  inputSourceMap?: import('source-map').RawSourceMap | undefined,
+  meta?: any
+): void;
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/types/loader/types.d.ts
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/types/loader/types.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/types/loader/types.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,24 @@
+export type ESModuleOptions = {
+  /**
+   * Files to explicitly exclude from flagged as ES Modules.
+   */
+  exclude?: string | RegExp | (string | RegExp)[] | undefined;
+  /**
+   * Files to explicitly include for flagged as ES Modules.
+   */
+  include?: string | RegExp | (string | RegExp)[] | undefined;
+};
+export type ReactRefreshLoaderOptions = {
+  /**
+   * Enables usage of ES6 `const` and `let` in generated runtime code.
+   */
+  const?: boolean | undefined;
+  /**
+   * Enables strict ES Modules compatible runtime.
+   */
+  esModule?: boolean | ESModuleOptions | undefined;
+};
+export type NormalizedLoaderOptions = import('type-fest').SetRequired<
+  ReactRefreshLoaderOptions,
+  'const'
+>;
Index: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/types/options/index.d.ts
===================================================================
--- frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/types/options/index.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/types/options/index.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,29 @@
+/**
+ * Sets a constant default value for the property when it is undefined.
+ * @template T
+ * @template {keyof T} Property
+ * @param {T} object An object.
+ * @param {Property} property A property of the provided object.
+ * @param {T[Property]} [defaultValue] The default value to set for the property.
+ * @returns {T[Property]} The defaulted property value.
+ */
+export function d<T, Property extends keyof T>(
+  object: T,
+  property: Property,
+  defaultValue?: T[Property] | undefined
+): T[Property];
+/**
+ * Resolves the value for a nested object option.
+ * @template T
+ * @template {keyof T} Property
+ * @template Result
+ * @param {T} object An object.
+ * @param {Property} property A property of the provided object.
+ * @param {function(T | undefined): Result} fn The handler to resolve the property's value.
+ * @returns {Result} The resolved option value.
+ */
+export function n<T, Property extends keyof T, Result>(
+  object: T,
+  property: Property,
+  fn: (arg0: T | undefined) => Result
+): Result;
