├── .gitignore
├── .jshintrc
├── README.md
├── blazor-output.js
├── build
├── .htaccess
├── css
│ └── site.css
├── images
│ ├── blazor-logo.png
│ └── react-logo.png
└── index.html
├── package-lock.json
├── package.json
├── serve.js
├── src
├── blazor
│ ├── App.razor
│ ├── BlazorChatApp.csproj
│ ├── Core
│ │ ├── ChatMessage.cs
│ │ ├── ChatMessageRepository.cs
│ │ └── TimeUtils.cs
│ ├── Pages
│ │ ├── Root.razor
│ │ └── _Imports.razor
│ ├── Program.cs
│ ├── Shared
│ │ ├── Chat.razor
│ │ ├── MainLayout.razor
│ │ └── NewChatMessage.razor
│ └── _Imports.razor
├── common
│ ├── ChatMessage.ts
│ ├── ChatMessageRepository.d.ts
│ ├── ChatMessageRepository.ts
│ └── index.ts
└── react
│ ├── components
│ ├── Chat.tsx
│ ├── ChatMessage.tsx
│ ├── NewChatMessage.tsx
│ └── Root.tsx
│ ├── core
│ └── TimeUtils.ts
│ └── index.tsx
├── tsconfig.json
└── webpack.config.js
/.gitignore:
--------------------------------------------------------------------------------
1 | *.user
2 |
3 | .vs
4 | node_modules
5 | bin
6 | obj
7 |
8 | /build/apps
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "esversion": 6
3 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React vs. Blazor
2 |
3 | This demo shows how React apps can live together with Blazor apps, which are basically C# apps running in the browser with the help of WebAssembly.
4 |
5 | ## Getting started
6 |
7 | To build the blazor app you need either Docker installed or you can follow the [instructions](https://dotnet.microsoft.com/apps/aspnet/web-apps/blazor) to install the appropriate .NET SDK locally. For the rest, you only need:
8 |
9 | ```
10 | npm install
11 | ```
12 |
13 | ### Build
14 |
15 | To build the project and run it locally run
16 |
17 | ```
18 | npm run build
19 | npm start
20 | ```
21 |
22 | Then you can access it at `http://localhost:8080/react-blazor/`.
23 |
24 | ## Questions & contribution
25 |
26 | You can follow me on Twitter [@boyanio](https://twitter.com/boyanio) and ask me any questions you might have. You can also open an issue here on GitHub. Pull Requests are welcome too :-)
27 |
--------------------------------------------------------------------------------
/blazor-output.js:
--------------------------------------------------------------------------------
1 | const { promisify } = require('util');
2 | const fs = require('fs');
3 | const rimraf = require('rimraf');
4 | const { ncp } = require('ncp');
5 |
6 | const fsAsync = ['exists', 'mkdir']
7 | .reduce((value, func) => Object.assign(value, { [func]: promisify(fs[func]) }), {});
8 | const rimrafAsync = promisify(rimraf);
9 | const ncpAsync = promisify(ncp);
10 |
11 | const run = async (buildConfiguration) => {
12 | const buildDir = `${__dirname}/build/apps/blazor`;
13 |
14 | if (await fsAsync.exists(buildDir)) {
15 | await rimrafAsync(buildDir);
16 | }
17 |
18 | await fsAsync.mkdir(buildDir, { recursive: true });
19 |
20 | const publishDir = `${__dirname}/src/blazor/bin/${buildConfiguration}/net5.0/publish/wwwroot`;
21 | await ncpAsync(`${publishDir}/_framework`, `${buildDir}/_framework`);
22 | };
23 |
24 |
25 | const buildConfiguration = process.argv.length > 2 ? process.argv[2] : 'Release';
26 | run(buildConfiguration);
--------------------------------------------------------------------------------
/build/.htaccess:
--------------------------------------------------------------------------------
1 | RewriteEngine On
2 | RewriteBase /react-blazor/
3 | Options +FollowSymLinks
4 |
5 | RewriteRule ^_framework/(.+) /react-blazor/apps/blazor/_framework/$1 [L]
--------------------------------------------------------------------------------
/build/css/site.css:
--------------------------------------------------------------------------------
1 | html, body {
2 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
3 | }
4 |
5 | .new-message-form {
6 | margin-bottom: 20px;
7 | }
8 |
9 | .chat-section {
10 | background-color: #F3F3F3;
11 | padding: 20px;
12 | }
13 |
14 | .chat-section ul {
15 | padding: 0;
16 | }
17 |
18 | .chat-section ul li {
19 | list-style: none;
20 | margin-top: 10px;
21 | }
22 |
23 | .chat-section ul li::after {
24 | clear: both;
25 | display: block;
26 | content: "";
27 | }
28 |
29 | .left-chat, .right-chat {
30 | margin-bottom: 20px;
31 | }
32 |
33 | .left-chat img, .right-chat img {
34 | width: 50px;
35 | height: 50px;
36 | float: left;
37 | margin: 0 10px;
38 | }
39 |
40 | .right-chat img {
41 | float: right;
42 | }
43 |
44 | .left-chat p, .right-chat p {
45 | background-color: #FD8468;
46 | padding: 10px;
47 | color: #fff;
48 | border-radius: 5px;
49 | float: left;
50 | width: 60%;
51 | margin-bottom: 0;
52 | font-weight: bold;
53 | }
54 |
55 | .left-chat span, .right-chat span {
56 | color: #808080;
57 | display: block;
58 | clear: both;
59 | }
60 |
61 | .left-chat span {
62 | float: left;
63 | margin-left: 70px;
64 | }
65 |
66 | .right-chat span {
67 | float: right;
68 | margin-right: 70px;
69 | }
70 |
71 | .right-chat p {
72 | float: right;
73 | background-color: #FFFFFF;
74 | color: #FD8468;
75 | }
--------------------------------------------------------------------------------
/build/images/blazor-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boyanio/react-blazor/8daa7b4792ddaaf1d2d7b76005641b62dfb8f308/build/images/blazor-logo.png
--------------------------------------------------------------------------------
/build/images/react-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/boyanio/react-blazor/8daa7b4792ddaaf1d2d7b76005641b62dfb8f308/build/images/react-logo.png
--------------------------------------------------------------------------------
/build/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | React vs. Blazor
8 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
React vs. Blazor
25 |
26 | This demo shows how React apps can live together with Blazor apps, which are basically C# apps running in the browser with
27 | the help of WebAssembly.
28 |
29 |
30 |
31 |
32 |
33 |
34 |
Loading React app...
35 |
36 |
37 |
Loading Blazor app...
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-blazor",
3 | "version": "0.1.0",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "react-blazor",
9 | "version": "0.1.0",
10 | "license": "MIT",
11 | "dependencies": {
12 | "react": "^18.2.0",
13 | "react-dom": "^18.2.0"
14 | },
15 | "devDependencies": {
16 | "@types/react": "^18.2.47",
17 | "@types/react-dom": "^18.2.18",
18 | "connect": "^3.7.0",
19 | "connect-modrewrite": "^0.10.2",
20 | "ncp": "^2.0.0",
21 | "rimraf": "^5.0.5",
22 | "serve-static": "^1.16.2",
23 | "ts-loader": "^9.5.1",
24 | "typescript": "^5.2.2",
25 | "webpack": "^5.94.0",
26 | "webpack-cli": "^5.1.4"
27 | }
28 | },
29 | "node_modules/@discoveryjs/json-ext": {
30 | "version": "0.5.7",
31 | "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz",
32 | "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==",
33 | "dev": true,
34 | "engines": {
35 | "node": ">=10.0.0"
36 | }
37 | },
38 | "node_modules/@isaacs/cliui": {
39 | "version": "8.0.2",
40 | "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
41 | "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
42 | "dev": true,
43 | "dependencies": {
44 | "string-width": "^5.1.2",
45 | "string-width-cjs": "npm:string-width@^4.2.0",
46 | "strip-ansi": "^7.0.1",
47 | "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
48 | "wrap-ansi": "^8.1.0",
49 | "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
50 | },
51 | "engines": {
52 | "node": ">=12"
53 | }
54 | },
55 | "node_modules/@jridgewell/gen-mapping": {
56 | "version": "0.3.3",
57 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
58 | "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
59 | "dev": true,
60 | "dependencies": {
61 | "@jridgewell/set-array": "^1.0.1",
62 | "@jridgewell/sourcemap-codec": "^1.4.10",
63 | "@jridgewell/trace-mapping": "^0.3.9"
64 | },
65 | "engines": {
66 | "node": ">=6.0.0"
67 | }
68 | },
69 | "node_modules/@jridgewell/resolve-uri": {
70 | "version": "3.1.1",
71 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
72 | "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
73 | "dev": true,
74 | "engines": {
75 | "node": ">=6.0.0"
76 | }
77 | },
78 | "node_modules/@jridgewell/set-array": {
79 | "version": "1.1.2",
80 | "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
81 | "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
82 | "dev": true,
83 | "engines": {
84 | "node": ">=6.0.0"
85 | }
86 | },
87 | "node_modules/@jridgewell/source-map": {
88 | "version": "0.3.5",
89 | "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz",
90 | "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==",
91 | "dev": true,
92 | "dependencies": {
93 | "@jridgewell/gen-mapping": "^0.3.0",
94 | "@jridgewell/trace-mapping": "^0.3.9"
95 | }
96 | },
97 | "node_modules/@jridgewell/sourcemap-codec": {
98 | "version": "1.4.15",
99 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
100 | "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
101 | "dev": true
102 | },
103 | "node_modules/@jridgewell/trace-mapping": {
104 | "version": "0.3.21",
105 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.21.tgz",
106 | "integrity": "sha512-SRfKmRe1KvYnxjEMtxEr+J4HIeMX5YBg/qhRHpxEIGjhX1rshcHlnFUE9K0GazhVKWM7B+nARSkV8LuvJdJ5/g==",
107 | "dev": true,
108 | "dependencies": {
109 | "@jridgewell/resolve-uri": "^3.1.0",
110 | "@jridgewell/sourcemap-codec": "^1.4.14"
111 | }
112 | },
113 | "node_modules/@pkgjs/parseargs": {
114 | "version": "0.11.0",
115 | "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
116 | "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
117 | "dev": true,
118 | "optional": true,
119 | "engines": {
120 | "node": ">=14"
121 | }
122 | },
123 | "node_modules/@types/estree": {
124 | "version": "1.0.5",
125 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
126 | "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
127 | "dev": true
128 | },
129 | "node_modules/@types/json-schema": {
130 | "version": "7.0.15",
131 | "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
132 | "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
133 | "dev": true
134 | },
135 | "node_modules/@types/node": {
136 | "version": "20.11.0",
137 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.0.tgz",
138 | "integrity": "sha512-o9bjXmDNcF7GbM4CNQpmi+TutCgap/K3w1JyKgxAjqx41zp9qlIAVFi0IhCNsJcXolEqLWhbFbEeL0PvYm4pcQ==",
139 | "dev": true,
140 | "dependencies": {
141 | "undici-types": "~5.26.4"
142 | }
143 | },
144 | "node_modules/@types/prop-types": {
145 | "version": "15.5.8",
146 | "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.5.8.tgz",
147 | "integrity": "sha512-3AQoUxQcQtLHsK25wtTWIoIpgYjH3vSDroZOUr7PpCHw/jLY1RB9z9E8dBT/OSmwStVgkRNvdh+ZHNiomRieaw==",
148 | "dev": true
149 | },
150 | "node_modules/@types/react": {
151 | "version": "18.2.47",
152 | "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.47.tgz",
153 | "integrity": "sha512-xquNkkOirwyCgoClNk85BjP+aqnIS+ckAJ8i37gAbDs14jfW/J23f2GItAf33oiUPQnqNMALiFeoM9Y5mbjpVQ==",
154 | "dev": true,
155 | "dependencies": {
156 | "@types/prop-types": "*",
157 | "@types/scheduler": "*",
158 | "csstype": "^3.0.2"
159 | }
160 | },
161 | "node_modules/@types/react-dom": {
162 | "version": "18.2.18",
163 | "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.18.tgz",
164 | "integrity": "sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw==",
165 | "dev": true,
166 | "dependencies": {
167 | "@types/react": "*"
168 | }
169 | },
170 | "node_modules/@types/scheduler": {
171 | "version": "0.16.8",
172 | "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz",
173 | "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==",
174 | "dev": true
175 | },
176 | "node_modules/@webassemblyjs/ast": {
177 | "version": "1.12.1",
178 | "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz",
179 | "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==",
180 | "dev": true,
181 | "dependencies": {
182 | "@webassemblyjs/helper-numbers": "1.11.6",
183 | "@webassemblyjs/helper-wasm-bytecode": "1.11.6"
184 | }
185 | },
186 | "node_modules/@webassemblyjs/floating-point-hex-parser": {
187 | "version": "1.11.6",
188 | "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz",
189 | "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==",
190 | "dev": true
191 | },
192 | "node_modules/@webassemblyjs/helper-api-error": {
193 | "version": "1.11.6",
194 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz",
195 | "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==",
196 | "dev": true
197 | },
198 | "node_modules/@webassemblyjs/helper-buffer": {
199 | "version": "1.12.1",
200 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz",
201 | "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==",
202 | "dev": true
203 | },
204 | "node_modules/@webassemblyjs/helper-numbers": {
205 | "version": "1.11.6",
206 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz",
207 | "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==",
208 | "dev": true,
209 | "dependencies": {
210 | "@webassemblyjs/floating-point-hex-parser": "1.11.6",
211 | "@webassemblyjs/helper-api-error": "1.11.6",
212 | "@xtuc/long": "4.2.2"
213 | }
214 | },
215 | "node_modules/@webassemblyjs/helper-wasm-bytecode": {
216 | "version": "1.11.6",
217 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz",
218 | "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==",
219 | "dev": true
220 | },
221 | "node_modules/@webassemblyjs/helper-wasm-section": {
222 | "version": "1.12.1",
223 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz",
224 | "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==",
225 | "dev": true,
226 | "dependencies": {
227 | "@webassemblyjs/ast": "1.12.1",
228 | "@webassemblyjs/helper-buffer": "1.12.1",
229 | "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
230 | "@webassemblyjs/wasm-gen": "1.12.1"
231 | }
232 | },
233 | "node_modules/@webassemblyjs/ieee754": {
234 | "version": "1.11.6",
235 | "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz",
236 | "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==",
237 | "dev": true,
238 | "dependencies": {
239 | "@xtuc/ieee754": "^1.2.0"
240 | }
241 | },
242 | "node_modules/@webassemblyjs/leb128": {
243 | "version": "1.11.6",
244 | "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz",
245 | "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==",
246 | "dev": true,
247 | "dependencies": {
248 | "@xtuc/long": "4.2.2"
249 | }
250 | },
251 | "node_modules/@webassemblyjs/utf8": {
252 | "version": "1.11.6",
253 | "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz",
254 | "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==",
255 | "dev": true
256 | },
257 | "node_modules/@webassemblyjs/wasm-edit": {
258 | "version": "1.12.1",
259 | "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz",
260 | "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==",
261 | "dev": true,
262 | "dependencies": {
263 | "@webassemblyjs/ast": "1.12.1",
264 | "@webassemblyjs/helper-buffer": "1.12.1",
265 | "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
266 | "@webassemblyjs/helper-wasm-section": "1.12.1",
267 | "@webassemblyjs/wasm-gen": "1.12.1",
268 | "@webassemblyjs/wasm-opt": "1.12.1",
269 | "@webassemblyjs/wasm-parser": "1.12.1",
270 | "@webassemblyjs/wast-printer": "1.12.1"
271 | }
272 | },
273 | "node_modules/@webassemblyjs/wasm-gen": {
274 | "version": "1.12.1",
275 | "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz",
276 | "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==",
277 | "dev": true,
278 | "dependencies": {
279 | "@webassemblyjs/ast": "1.12.1",
280 | "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
281 | "@webassemblyjs/ieee754": "1.11.6",
282 | "@webassemblyjs/leb128": "1.11.6",
283 | "@webassemblyjs/utf8": "1.11.6"
284 | }
285 | },
286 | "node_modules/@webassemblyjs/wasm-opt": {
287 | "version": "1.12.1",
288 | "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz",
289 | "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==",
290 | "dev": true,
291 | "dependencies": {
292 | "@webassemblyjs/ast": "1.12.1",
293 | "@webassemblyjs/helper-buffer": "1.12.1",
294 | "@webassemblyjs/wasm-gen": "1.12.1",
295 | "@webassemblyjs/wasm-parser": "1.12.1"
296 | }
297 | },
298 | "node_modules/@webassemblyjs/wasm-parser": {
299 | "version": "1.12.1",
300 | "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz",
301 | "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==",
302 | "dev": true,
303 | "dependencies": {
304 | "@webassemblyjs/ast": "1.12.1",
305 | "@webassemblyjs/helper-api-error": "1.11.6",
306 | "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
307 | "@webassemblyjs/ieee754": "1.11.6",
308 | "@webassemblyjs/leb128": "1.11.6",
309 | "@webassemblyjs/utf8": "1.11.6"
310 | }
311 | },
312 | "node_modules/@webassemblyjs/wast-printer": {
313 | "version": "1.12.1",
314 | "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz",
315 | "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==",
316 | "dev": true,
317 | "dependencies": {
318 | "@webassemblyjs/ast": "1.12.1",
319 | "@xtuc/long": "4.2.2"
320 | }
321 | },
322 | "node_modules/@webpack-cli/configtest": {
323 | "version": "2.1.1",
324 | "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz",
325 | "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==",
326 | "dev": true,
327 | "engines": {
328 | "node": ">=14.15.0"
329 | },
330 | "peerDependencies": {
331 | "webpack": "5.x.x",
332 | "webpack-cli": "5.x.x"
333 | }
334 | },
335 | "node_modules/@webpack-cli/info": {
336 | "version": "2.0.2",
337 | "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz",
338 | "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==",
339 | "dev": true,
340 | "engines": {
341 | "node": ">=14.15.0"
342 | },
343 | "peerDependencies": {
344 | "webpack": "5.x.x",
345 | "webpack-cli": "5.x.x"
346 | }
347 | },
348 | "node_modules/@webpack-cli/serve": {
349 | "version": "2.0.5",
350 | "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz",
351 | "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==",
352 | "dev": true,
353 | "engines": {
354 | "node": ">=14.15.0"
355 | },
356 | "peerDependencies": {
357 | "webpack": "5.x.x",
358 | "webpack-cli": "5.x.x"
359 | },
360 | "peerDependenciesMeta": {
361 | "webpack-dev-server": {
362 | "optional": true
363 | }
364 | }
365 | },
366 | "node_modules/@xtuc/ieee754": {
367 | "version": "1.2.0",
368 | "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
369 | "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
370 | "dev": true
371 | },
372 | "node_modules/@xtuc/long": {
373 | "version": "4.2.2",
374 | "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
375 | "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
376 | "dev": true
377 | },
378 | "node_modules/acorn": {
379 | "version": "8.11.3",
380 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
381 | "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
382 | "dev": true,
383 | "bin": {
384 | "acorn": "bin/acorn"
385 | },
386 | "engines": {
387 | "node": ">=0.4.0"
388 | }
389 | },
390 | "node_modules/acorn-import-attributes": {
391 | "version": "1.9.5",
392 | "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz",
393 | "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==",
394 | "dev": true,
395 | "peerDependencies": {
396 | "acorn": "^8"
397 | }
398 | },
399 | "node_modules/ajv": {
400 | "version": "6.12.6",
401 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
402 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
403 | "dev": true,
404 | "dependencies": {
405 | "fast-deep-equal": "^3.1.1",
406 | "fast-json-stable-stringify": "^2.0.0",
407 | "json-schema-traverse": "^0.4.1",
408 | "uri-js": "^4.2.2"
409 | },
410 | "funding": {
411 | "type": "github",
412 | "url": "https://github.com/sponsors/epoberezkin"
413 | }
414 | },
415 | "node_modules/ajv-keywords": {
416 | "version": "3.5.2",
417 | "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
418 | "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
419 | "dev": true,
420 | "peerDependencies": {
421 | "ajv": "^6.9.1"
422 | }
423 | },
424 | "node_modules/ansi-regex": {
425 | "version": "6.0.1",
426 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
427 | "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
428 | "dev": true,
429 | "engines": {
430 | "node": ">=12"
431 | },
432 | "funding": {
433 | "url": "https://github.com/chalk/ansi-regex?sponsor=1"
434 | }
435 | },
436 | "node_modules/ansi-styles": {
437 | "version": "6.2.1",
438 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
439 | "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
440 | "dev": true,
441 | "engines": {
442 | "node": ">=12"
443 | },
444 | "funding": {
445 | "url": "https://github.com/chalk/ansi-styles?sponsor=1"
446 | }
447 | },
448 | "node_modules/balanced-match": {
449 | "version": "1.0.2",
450 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
451 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
452 | "dev": true
453 | },
454 | "node_modules/brace-expansion": {
455 | "version": "2.0.1",
456 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
457 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
458 | "dev": true,
459 | "dependencies": {
460 | "balanced-match": "^1.0.0"
461 | }
462 | },
463 | "node_modules/braces": {
464 | "version": "3.0.3",
465 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
466 | "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
467 | "dev": true,
468 | "dependencies": {
469 | "fill-range": "^7.1.1"
470 | },
471 | "engines": {
472 | "node": ">=8"
473 | }
474 | },
475 | "node_modules/browserslist": {
476 | "version": "4.22.2",
477 | "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz",
478 | "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==",
479 | "dev": true,
480 | "funding": [
481 | {
482 | "type": "opencollective",
483 | "url": "https://opencollective.com/browserslist"
484 | },
485 | {
486 | "type": "tidelift",
487 | "url": "https://tidelift.com/funding/github/npm/browserslist"
488 | },
489 | {
490 | "type": "github",
491 | "url": "https://github.com/sponsors/ai"
492 | }
493 | ],
494 | "dependencies": {
495 | "caniuse-lite": "^1.0.30001565",
496 | "electron-to-chromium": "^1.4.601",
497 | "node-releases": "^2.0.14",
498 | "update-browserslist-db": "^1.0.13"
499 | },
500 | "bin": {
501 | "browserslist": "cli.js"
502 | },
503 | "engines": {
504 | "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
505 | }
506 | },
507 | "node_modules/buffer-from": {
508 | "version": "1.1.1",
509 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
510 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
511 | "dev": true
512 | },
513 | "node_modules/caniuse-lite": {
514 | "version": "1.0.30001576",
515 | "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001576.tgz",
516 | "integrity": "sha512-ff5BdakGe2P3SQsMsiqmt1Lc8221NR1VzHj5jXN5vBny9A6fpze94HiVV/n7XRosOlsShJcvMv5mdnpjOGCEgg==",
517 | "dev": true,
518 | "funding": [
519 | {
520 | "type": "opencollective",
521 | "url": "https://opencollective.com/browserslist"
522 | },
523 | {
524 | "type": "tidelift",
525 | "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
526 | },
527 | {
528 | "type": "github",
529 | "url": "https://github.com/sponsors/ai"
530 | }
531 | ]
532 | },
533 | "node_modules/chrome-trace-event": {
534 | "version": "1.0.2",
535 | "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz",
536 | "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==",
537 | "dev": true,
538 | "dependencies": {
539 | "tslib": "^1.9.0"
540 | },
541 | "engines": {
542 | "node": ">=6.0"
543 | }
544 | },
545 | "node_modules/clone-deep": {
546 | "version": "4.0.1",
547 | "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
548 | "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==",
549 | "dev": true,
550 | "dependencies": {
551 | "is-plain-object": "^2.0.4",
552 | "kind-of": "^6.0.2",
553 | "shallow-clone": "^3.0.0"
554 | },
555 | "engines": {
556 | "node": ">=6"
557 | }
558 | },
559 | "node_modules/color-convert": {
560 | "version": "2.0.1",
561 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
562 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
563 | "dev": true,
564 | "dependencies": {
565 | "color-name": "~1.1.4"
566 | },
567 | "engines": {
568 | "node": ">=7.0.0"
569 | }
570 | },
571 | "node_modules/color-name": {
572 | "version": "1.1.4",
573 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
574 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
575 | "dev": true
576 | },
577 | "node_modules/colorette": {
578 | "version": "2.0.20",
579 | "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
580 | "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
581 | "dev": true
582 | },
583 | "node_modules/commander": {
584 | "version": "2.20.3",
585 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
586 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
587 | "dev": true
588 | },
589 | "node_modules/connect": {
590 | "version": "3.7.0",
591 | "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz",
592 | "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==",
593 | "dev": true,
594 | "dependencies": {
595 | "debug": "2.6.9",
596 | "finalhandler": "1.1.2",
597 | "parseurl": "~1.3.3",
598 | "utils-merge": "1.0.1"
599 | },
600 | "engines": {
601 | "node": ">= 0.10.0"
602 | }
603 | },
604 | "node_modules/connect-modrewrite": {
605 | "version": "0.10.2",
606 | "resolved": "https://registry.npmjs.org/connect-modrewrite/-/connect-modrewrite-0.10.2.tgz",
607 | "integrity": "sha512-37+kS9t26vxjW5ErNrr8d04F7Us1EH7XhHtxSm8yE8kO2uDF2DsPI+qI2wCeBSaoakXKit0/88sg4vL2Wl8tDw==",
608 | "dev": true,
609 | "dependencies": {
610 | "qs": "^6.3.1"
611 | }
612 | },
613 | "node_modules/cross-spawn": {
614 | "version": "7.0.3",
615 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
616 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
617 | "dev": true,
618 | "dependencies": {
619 | "path-key": "^3.1.0",
620 | "shebang-command": "^2.0.0",
621 | "which": "^2.0.1"
622 | },
623 | "engines": {
624 | "node": ">= 8"
625 | }
626 | },
627 | "node_modules/csstype": {
628 | "version": "3.1.3",
629 | "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
630 | "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
631 | "dev": true
632 | },
633 | "node_modules/debug": {
634 | "version": "2.6.9",
635 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
636 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
637 | "dev": true,
638 | "dependencies": {
639 | "ms": "2.0.0"
640 | }
641 | },
642 | "node_modules/depd": {
643 | "version": "2.0.0",
644 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
645 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
646 | "dev": true,
647 | "engines": {
648 | "node": ">= 0.8"
649 | }
650 | },
651 | "node_modules/destroy": {
652 | "version": "1.2.0",
653 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
654 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
655 | "dev": true,
656 | "engines": {
657 | "node": ">= 0.8",
658 | "npm": "1.2.8000 || >= 1.4.16"
659 | }
660 | },
661 | "node_modules/eastasianwidth": {
662 | "version": "0.2.0",
663 | "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
664 | "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
665 | "dev": true
666 | },
667 | "node_modules/ee-first": {
668 | "version": "1.1.1",
669 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
670 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
671 | "dev": true
672 | },
673 | "node_modules/electron-to-chromium": {
674 | "version": "1.4.630",
675 | "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.630.tgz",
676 | "integrity": "sha512-osHqhtjojpCsACVnuD11xO5g9xaCyw7Qqn/C2KParkMv42i8jrJJgx3g7mkHfpxwhy9MnOJr8+pKOdZ7qzgizg==",
677 | "dev": true
678 | },
679 | "node_modules/emoji-regex": {
680 | "version": "9.2.2",
681 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
682 | "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
683 | "dev": true
684 | },
685 | "node_modules/encodeurl": {
686 | "version": "1.0.2",
687 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
688 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
689 | "dev": true,
690 | "engines": {
691 | "node": ">= 0.8"
692 | }
693 | },
694 | "node_modules/enhanced-resolve": {
695 | "version": "5.17.1",
696 | "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz",
697 | "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==",
698 | "dev": true,
699 | "dependencies": {
700 | "graceful-fs": "^4.2.4",
701 | "tapable": "^2.2.0"
702 | },
703 | "engines": {
704 | "node": ">=10.13.0"
705 | }
706 | },
707 | "node_modules/envinfo": {
708 | "version": "7.11.0",
709 | "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.0.tgz",
710 | "integrity": "sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg==",
711 | "dev": true,
712 | "bin": {
713 | "envinfo": "dist/cli.js"
714 | },
715 | "engines": {
716 | "node": ">=4"
717 | }
718 | },
719 | "node_modules/es-module-lexer": {
720 | "version": "1.4.1",
721 | "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz",
722 | "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==",
723 | "dev": true
724 | },
725 | "node_modules/escalade": {
726 | "version": "3.1.1",
727 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
728 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
729 | "dev": true,
730 | "engines": {
731 | "node": ">=6"
732 | }
733 | },
734 | "node_modules/escape-html": {
735 | "version": "1.0.3",
736 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
737 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
738 | "dev": true
739 | },
740 | "node_modules/eslint-scope": {
741 | "version": "5.1.1",
742 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
743 | "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
744 | "dev": true,
745 | "dependencies": {
746 | "esrecurse": "^4.3.0",
747 | "estraverse": "^4.1.1"
748 | },
749 | "engines": {
750 | "node": ">=8.0.0"
751 | }
752 | },
753 | "node_modules/esrecurse": {
754 | "version": "4.3.0",
755 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
756 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
757 | "dev": true,
758 | "dependencies": {
759 | "estraverse": "^5.2.0"
760 | },
761 | "engines": {
762 | "node": ">=4.0"
763 | }
764 | },
765 | "node_modules/esrecurse/node_modules/estraverse": {
766 | "version": "5.3.0",
767 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
768 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
769 | "dev": true,
770 | "engines": {
771 | "node": ">=4.0"
772 | }
773 | },
774 | "node_modules/estraverse": {
775 | "version": "4.3.0",
776 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
777 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
778 | "dev": true,
779 | "engines": {
780 | "node": ">=4.0"
781 | }
782 | },
783 | "node_modules/etag": {
784 | "version": "1.8.1",
785 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
786 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
787 | "dev": true,
788 | "engines": {
789 | "node": ">= 0.6"
790 | }
791 | },
792 | "node_modules/events": {
793 | "version": "3.3.0",
794 | "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
795 | "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
796 | "dev": true,
797 | "engines": {
798 | "node": ">=0.8.x"
799 | }
800 | },
801 | "node_modules/fast-deep-equal": {
802 | "version": "3.1.3",
803 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
804 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
805 | "dev": true
806 | },
807 | "node_modules/fast-json-stable-stringify": {
808 | "version": "2.1.0",
809 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
810 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
811 | "dev": true
812 | },
813 | "node_modules/fastest-levenshtein": {
814 | "version": "1.0.16",
815 | "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
816 | "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
817 | "dev": true,
818 | "engines": {
819 | "node": ">= 4.9.1"
820 | }
821 | },
822 | "node_modules/fill-range": {
823 | "version": "7.1.1",
824 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
825 | "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
826 | "dev": true,
827 | "dependencies": {
828 | "to-regex-range": "^5.0.1"
829 | },
830 | "engines": {
831 | "node": ">=8"
832 | }
833 | },
834 | "node_modules/finalhandler": {
835 | "version": "1.1.2",
836 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
837 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
838 | "dev": true,
839 | "dependencies": {
840 | "debug": "2.6.9",
841 | "encodeurl": "~1.0.2",
842 | "escape-html": "~1.0.3",
843 | "on-finished": "~2.3.0",
844 | "parseurl": "~1.3.3",
845 | "statuses": "~1.5.0",
846 | "unpipe": "~1.0.0"
847 | },
848 | "engines": {
849 | "node": ">= 0.8"
850 | }
851 | },
852 | "node_modules/find-up": {
853 | "version": "4.1.0",
854 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
855 | "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
856 | "dev": true,
857 | "dependencies": {
858 | "locate-path": "^5.0.0",
859 | "path-exists": "^4.0.0"
860 | },
861 | "engines": {
862 | "node": ">=8"
863 | }
864 | },
865 | "node_modules/flat": {
866 | "version": "5.0.2",
867 | "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
868 | "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
869 | "dev": true,
870 | "bin": {
871 | "flat": "cli.js"
872 | }
873 | },
874 | "node_modules/foreground-child": {
875 | "version": "3.1.1",
876 | "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz",
877 | "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==",
878 | "dev": true,
879 | "dependencies": {
880 | "cross-spawn": "^7.0.0",
881 | "signal-exit": "^4.0.1"
882 | },
883 | "engines": {
884 | "node": ">=14"
885 | },
886 | "funding": {
887 | "url": "https://github.com/sponsors/isaacs"
888 | }
889 | },
890 | "node_modules/fresh": {
891 | "version": "0.5.2",
892 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
893 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
894 | "dev": true,
895 | "engines": {
896 | "node": ">= 0.6"
897 | }
898 | },
899 | "node_modules/function-bind": {
900 | "version": "1.1.2",
901 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
902 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
903 | "dev": true,
904 | "funding": {
905 | "url": "https://github.com/sponsors/ljharb"
906 | }
907 | },
908 | "node_modules/glob": {
909 | "version": "10.3.10",
910 | "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz",
911 | "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==",
912 | "dev": true,
913 | "dependencies": {
914 | "foreground-child": "^3.1.0",
915 | "jackspeak": "^2.3.5",
916 | "minimatch": "^9.0.1",
917 | "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0",
918 | "path-scurry": "^1.10.1"
919 | },
920 | "bin": {
921 | "glob": "dist/esm/bin.mjs"
922 | },
923 | "engines": {
924 | "node": ">=16 || 14 >=14.17"
925 | },
926 | "funding": {
927 | "url": "https://github.com/sponsors/isaacs"
928 | }
929 | },
930 | "node_modules/glob-to-regexp": {
931 | "version": "0.4.1",
932 | "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
933 | "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
934 | "dev": true
935 | },
936 | "node_modules/graceful-fs": {
937 | "version": "4.2.11",
938 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
939 | "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
940 | "dev": true
941 | },
942 | "node_modules/hasown": {
943 | "version": "2.0.0",
944 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz",
945 | "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==",
946 | "dev": true,
947 | "dependencies": {
948 | "function-bind": "^1.1.2"
949 | },
950 | "engines": {
951 | "node": ">= 0.4"
952 | }
953 | },
954 | "node_modules/http-errors": {
955 | "version": "2.0.0",
956 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
957 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
958 | "dev": true,
959 | "dependencies": {
960 | "depd": "2.0.0",
961 | "inherits": "2.0.4",
962 | "setprototypeof": "1.2.0",
963 | "statuses": "2.0.1",
964 | "toidentifier": "1.0.1"
965 | },
966 | "engines": {
967 | "node": ">= 0.8"
968 | }
969 | },
970 | "node_modules/http-errors/node_modules/statuses": {
971 | "version": "2.0.1",
972 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
973 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
974 | "dev": true,
975 | "engines": {
976 | "node": ">= 0.8"
977 | }
978 | },
979 | "node_modules/import-local": {
980 | "version": "3.1.0",
981 | "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz",
982 | "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==",
983 | "dev": true,
984 | "dependencies": {
985 | "pkg-dir": "^4.2.0",
986 | "resolve-cwd": "^3.0.0"
987 | },
988 | "bin": {
989 | "import-local-fixture": "fixtures/cli.js"
990 | },
991 | "engines": {
992 | "node": ">=8"
993 | },
994 | "funding": {
995 | "url": "https://github.com/sponsors/sindresorhus"
996 | }
997 | },
998 | "node_modules/inherits": {
999 | "version": "2.0.4",
1000 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
1001 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
1002 | "dev": true
1003 | },
1004 | "node_modules/interpret": {
1005 | "version": "3.1.1",
1006 | "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz",
1007 | "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==",
1008 | "dev": true,
1009 | "engines": {
1010 | "node": ">=10.13.0"
1011 | }
1012 | },
1013 | "node_modules/is-core-module": {
1014 | "version": "2.13.1",
1015 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz",
1016 | "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==",
1017 | "dev": true,
1018 | "dependencies": {
1019 | "hasown": "^2.0.0"
1020 | },
1021 | "funding": {
1022 | "url": "https://github.com/sponsors/ljharb"
1023 | }
1024 | },
1025 | "node_modules/is-fullwidth-code-point": {
1026 | "version": "3.0.0",
1027 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
1028 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
1029 | "dev": true,
1030 | "engines": {
1031 | "node": ">=8"
1032 | }
1033 | },
1034 | "node_modules/is-number": {
1035 | "version": "7.0.0",
1036 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
1037 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
1038 | "dev": true,
1039 | "engines": {
1040 | "node": ">=0.12.0"
1041 | }
1042 | },
1043 | "node_modules/is-plain-object": {
1044 | "version": "2.0.4",
1045 | "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
1046 | "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
1047 | "dev": true,
1048 | "dependencies": {
1049 | "isobject": "^3.0.1"
1050 | },
1051 | "engines": {
1052 | "node": ">=0.10.0"
1053 | }
1054 | },
1055 | "node_modules/isexe": {
1056 | "version": "2.0.0",
1057 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
1058 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
1059 | "dev": true
1060 | },
1061 | "node_modules/isobject": {
1062 | "version": "3.0.1",
1063 | "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
1064 | "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
1065 | "dev": true,
1066 | "engines": {
1067 | "node": ">=0.10.0"
1068 | }
1069 | },
1070 | "node_modules/jackspeak": {
1071 | "version": "2.3.6",
1072 | "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz",
1073 | "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==",
1074 | "dev": true,
1075 | "dependencies": {
1076 | "@isaacs/cliui": "^8.0.2"
1077 | },
1078 | "engines": {
1079 | "node": ">=14"
1080 | },
1081 | "funding": {
1082 | "url": "https://github.com/sponsors/isaacs"
1083 | },
1084 | "optionalDependencies": {
1085 | "@pkgjs/parseargs": "^0.11.0"
1086 | }
1087 | },
1088 | "node_modules/jest-worker": {
1089 | "version": "27.5.1",
1090 | "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
1091 | "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==",
1092 | "dev": true,
1093 | "dependencies": {
1094 | "@types/node": "*",
1095 | "merge-stream": "^2.0.0",
1096 | "supports-color": "^8.0.0"
1097 | },
1098 | "engines": {
1099 | "node": ">= 10.13.0"
1100 | }
1101 | },
1102 | "node_modules/jest-worker/node_modules/has-flag": {
1103 | "version": "4.0.0",
1104 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
1105 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
1106 | "dev": true,
1107 | "engines": {
1108 | "node": ">=8"
1109 | }
1110 | },
1111 | "node_modules/jest-worker/node_modules/supports-color": {
1112 | "version": "8.1.1",
1113 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
1114 | "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
1115 | "dev": true,
1116 | "dependencies": {
1117 | "has-flag": "^4.0.0"
1118 | },
1119 | "engines": {
1120 | "node": ">=10"
1121 | },
1122 | "funding": {
1123 | "url": "https://github.com/chalk/supports-color?sponsor=1"
1124 | }
1125 | },
1126 | "node_modules/js-tokens": {
1127 | "version": "4.0.0",
1128 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
1129 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
1130 | },
1131 | "node_modules/json-parse-even-better-errors": {
1132 | "version": "2.3.1",
1133 | "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
1134 | "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
1135 | "dev": true
1136 | },
1137 | "node_modules/json-schema-traverse": {
1138 | "version": "0.4.1",
1139 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
1140 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
1141 | "dev": true
1142 | },
1143 | "node_modules/kind-of": {
1144 | "version": "6.0.3",
1145 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
1146 | "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
1147 | "dev": true,
1148 | "engines": {
1149 | "node": ">=0.10.0"
1150 | }
1151 | },
1152 | "node_modules/loader-runner": {
1153 | "version": "4.3.0",
1154 | "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
1155 | "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==",
1156 | "dev": true,
1157 | "engines": {
1158 | "node": ">=6.11.5"
1159 | }
1160 | },
1161 | "node_modules/locate-path": {
1162 | "version": "5.0.0",
1163 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
1164 | "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
1165 | "dev": true,
1166 | "dependencies": {
1167 | "p-locate": "^4.1.0"
1168 | },
1169 | "engines": {
1170 | "node": ">=8"
1171 | }
1172 | },
1173 | "node_modules/loose-envify": {
1174 | "version": "1.4.0",
1175 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
1176 | "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
1177 | "dependencies": {
1178 | "js-tokens": "^3.0.0 || ^4.0.0"
1179 | },
1180 | "bin": {
1181 | "loose-envify": "cli.js"
1182 | }
1183 | },
1184 | "node_modules/lru-cache": {
1185 | "version": "6.0.0",
1186 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
1187 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
1188 | "dev": true,
1189 | "dependencies": {
1190 | "yallist": "^4.0.0"
1191 | },
1192 | "engines": {
1193 | "node": ">=10"
1194 | }
1195 | },
1196 | "node_modules/merge-stream": {
1197 | "version": "2.0.0",
1198 | "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
1199 | "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
1200 | "dev": true
1201 | },
1202 | "node_modules/mime": {
1203 | "version": "1.6.0",
1204 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
1205 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
1206 | "dev": true,
1207 | "bin": {
1208 | "mime": "cli.js"
1209 | },
1210 | "engines": {
1211 | "node": ">=4"
1212 | }
1213 | },
1214 | "node_modules/mime-db": {
1215 | "version": "1.52.0",
1216 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
1217 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
1218 | "dev": true,
1219 | "engines": {
1220 | "node": ">= 0.6"
1221 | }
1222 | },
1223 | "node_modules/mime-types": {
1224 | "version": "2.1.35",
1225 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
1226 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
1227 | "dev": true,
1228 | "dependencies": {
1229 | "mime-db": "1.52.0"
1230 | },
1231 | "engines": {
1232 | "node": ">= 0.6"
1233 | }
1234 | },
1235 | "node_modules/minimatch": {
1236 | "version": "9.0.3",
1237 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
1238 | "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
1239 | "dev": true,
1240 | "dependencies": {
1241 | "brace-expansion": "^2.0.1"
1242 | },
1243 | "engines": {
1244 | "node": ">=16 || 14 >=14.17"
1245 | },
1246 | "funding": {
1247 | "url": "https://github.com/sponsors/isaacs"
1248 | }
1249 | },
1250 | "node_modules/minipass": {
1251 | "version": "7.0.4",
1252 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz",
1253 | "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==",
1254 | "dev": true,
1255 | "engines": {
1256 | "node": ">=16 || 14 >=14.17"
1257 | }
1258 | },
1259 | "node_modules/ms": {
1260 | "version": "2.0.0",
1261 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
1262 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
1263 | "dev": true
1264 | },
1265 | "node_modules/ncp": {
1266 | "version": "2.0.0",
1267 | "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz",
1268 | "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=",
1269 | "dev": true,
1270 | "bin": {
1271 | "ncp": "bin/ncp"
1272 | }
1273 | },
1274 | "node_modules/neo-async": {
1275 | "version": "2.6.2",
1276 | "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
1277 | "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
1278 | "dev": true
1279 | },
1280 | "node_modules/node-releases": {
1281 | "version": "2.0.14",
1282 | "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
1283 | "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
1284 | "dev": true
1285 | },
1286 | "node_modules/on-finished": {
1287 | "version": "2.3.0",
1288 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
1289 | "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==",
1290 | "dev": true,
1291 | "dependencies": {
1292 | "ee-first": "1.1.1"
1293 | },
1294 | "engines": {
1295 | "node": ">= 0.8"
1296 | }
1297 | },
1298 | "node_modules/p-limit": {
1299 | "version": "2.3.0",
1300 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
1301 | "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
1302 | "dev": true,
1303 | "dependencies": {
1304 | "p-try": "^2.0.0"
1305 | },
1306 | "engines": {
1307 | "node": ">=6"
1308 | },
1309 | "funding": {
1310 | "url": "https://github.com/sponsors/sindresorhus"
1311 | }
1312 | },
1313 | "node_modules/p-locate": {
1314 | "version": "4.1.0",
1315 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
1316 | "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
1317 | "dev": true,
1318 | "dependencies": {
1319 | "p-limit": "^2.2.0"
1320 | },
1321 | "engines": {
1322 | "node": ">=8"
1323 | }
1324 | },
1325 | "node_modules/p-try": {
1326 | "version": "2.2.0",
1327 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
1328 | "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
1329 | "dev": true,
1330 | "engines": {
1331 | "node": ">=6"
1332 | }
1333 | },
1334 | "node_modules/parseurl": {
1335 | "version": "1.3.3",
1336 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
1337 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
1338 | "dev": true,
1339 | "engines": {
1340 | "node": ">= 0.8"
1341 | }
1342 | },
1343 | "node_modules/path-exists": {
1344 | "version": "4.0.0",
1345 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
1346 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
1347 | "dev": true,
1348 | "engines": {
1349 | "node": ">=8"
1350 | }
1351 | },
1352 | "node_modules/path-key": {
1353 | "version": "3.1.1",
1354 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
1355 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
1356 | "dev": true,
1357 | "engines": {
1358 | "node": ">=8"
1359 | }
1360 | },
1361 | "node_modules/path-parse": {
1362 | "version": "1.0.7",
1363 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
1364 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
1365 | "dev": true
1366 | },
1367 | "node_modules/path-scurry": {
1368 | "version": "1.10.1",
1369 | "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz",
1370 | "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==",
1371 | "dev": true,
1372 | "dependencies": {
1373 | "lru-cache": "^9.1.1 || ^10.0.0",
1374 | "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
1375 | },
1376 | "engines": {
1377 | "node": ">=16 || 14 >=14.17"
1378 | },
1379 | "funding": {
1380 | "url": "https://github.com/sponsors/isaacs"
1381 | }
1382 | },
1383 | "node_modules/path-scurry/node_modules/lru-cache": {
1384 | "version": "10.1.0",
1385 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz",
1386 | "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==",
1387 | "dev": true,
1388 | "engines": {
1389 | "node": "14 || >=16.14"
1390 | }
1391 | },
1392 | "node_modules/picocolors": {
1393 | "version": "1.0.0",
1394 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
1395 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
1396 | "dev": true
1397 | },
1398 | "node_modules/picomatch": {
1399 | "version": "2.3.1",
1400 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
1401 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
1402 | "dev": true,
1403 | "engines": {
1404 | "node": ">=8.6"
1405 | },
1406 | "funding": {
1407 | "url": "https://github.com/sponsors/jonschlinkert"
1408 | }
1409 | },
1410 | "node_modules/pkg-dir": {
1411 | "version": "4.2.0",
1412 | "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
1413 | "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
1414 | "dev": true,
1415 | "dependencies": {
1416 | "find-up": "^4.0.0"
1417 | },
1418 | "engines": {
1419 | "node": ">=8"
1420 | }
1421 | },
1422 | "node_modules/punycode": {
1423 | "version": "2.3.1",
1424 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
1425 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
1426 | "dev": true,
1427 | "engines": {
1428 | "node": ">=6"
1429 | }
1430 | },
1431 | "node_modules/qs": {
1432 | "version": "6.5.2",
1433 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
1434 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
1435 | "dev": true,
1436 | "engines": {
1437 | "node": ">=0.6"
1438 | }
1439 | },
1440 | "node_modules/randombytes": {
1441 | "version": "2.1.0",
1442 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
1443 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
1444 | "dev": true,
1445 | "dependencies": {
1446 | "safe-buffer": "^5.1.0"
1447 | }
1448 | },
1449 | "node_modules/range-parser": {
1450 | "version": "1.2.1",
1451 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
1452 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
1453 | "dev": true,
1454 | "engines": {
1455 | "node": ">= 0.6"
1456 | }
1457 | },
1458 | "node_modules/react": {
1459 | "version": "18.2.0",
1460 | "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
1461 | "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
1462 | "dependencies": {
1463 | "loose-envify": "^1.1.0"
1464 | },
1465 | "engines": {
1466 | "node": ">=0.10.0"
1467 | }
1468 | },
1469 | "node_modules/react-dom": {
1470 | "version": "18.2.0",
1471 | "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
1472 | "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
1473 | "dependencies": {
1474 | "loose-envify": "^1.1.0",
1475 | "scheduler": "^0.23.0"
1476 | },
1477 | "peerDependencies": {
1478 | "react": "^18.2.0"
1479 | }
1480 | },
1481 | "node_modules/rechoir": {
1482 | "version": "0.8.0",
1483 | "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz",
1484 | "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==",
1485 | "dev": true,
1486 | "dependencies": {
1487 | "resolve": "^1.20.0"
1488 | },
1489 | "engines": {
1490 | "node": ">= 10.13.0"
1491 | }
1492 | },
1493 | "node_modules/resolve": {
1494 | "version": "1.22.8",
1495 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
1496 | "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
1497 | "dev": true,
1498 | "dependencies": {
1499 | "is-core-module": "^2.13.0",
1500 | "path-parse": "^1.0.7",
1501 | "supports-preserve-symlinks-flag": "^1.0.0"
1502 | },
1503 | "bin": {
1504 | "resolve": "bin/resolve"
1505 | },
1506 | "funding": {
1507 | "url": "https://github.com/sponsors/ljharb"
1508 | }
1509 | },
1510 | "node_modules/resolve-cwd": {
1511 | "version": "3.0.0",
1512 | "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
1513 | "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
1514 | "dev": true,
1515 | "dependencies": {
1516 | "resolve-from": "^5.0.0"
1517 | },
1518 | "engines": {
1519 | "node": ">=8"
1520 | }
1521 | },
1522 | "node_modules/resolve-from": {
1523 | "version": "5.0.0",
1524 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
1525 | "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
1526 | "dev": true,
1527 | "engines": {
1528 | "node": ">=8"
1529 | }
1530 | },
1531 | "node_modules/rimraf": {
1532 | "version": "5.0.5",
1533 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz",
1534 | "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==",
1535 | "dev": true,
1536 | "dependencies": {
1537 | "glob": "^10.3.7"
1538 | },
1539 | "bin": {
1540 | "rimraf": "dist/esm/bin.mjs"
1541 | },
1542 | "engines": {
1543 | "node": ">=14"
1544 | },
1545 | "funding": {
1546 | "url": "https://github.com/sponsors/isaacs"
1547 | }
1548 | },
1549 | "node_modules/safe-buffer": {
1550 | "version": "5.1.2",
1551 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
1552 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
1553 | "dev": true
1554 | },
1555 | "node_modules/scheduler": {
1556 | "version": "0.23.0",
1557 | "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
1558 | "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
1559 | "dependencies": {
1560 | "loose-envify": "^1.1.0"
1561 | }
1562 | },
1563 | "node_modules/schema-utils": {
1564 | "version": "3.3.0",
1565 | "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
1566 | "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
1567 | "dev": true,
1568 | "dependencies": {
1569 | "@types/json-schema": "^7.0.8",
1570 | "ajv": "^6.12.5",
1571 | "ajv-keywords": "^3.5.2"
1572 | },
1573 | "engines": {
1574 | "node": ">= 10.13.0"
1575 | },
1576 | "funding": {
1577 | "type": "opencollective",
1578 | "url": "https://opencollective.com/webpack"
1579 | }
1580 | },
1581 | "node_modules/semver": {
1582 | "version": "7.5.4",
1583 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
1584 | "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
1585 | "dev": true,
1586 | "dependencies": {
1587 | "lru-cache": "^6.0.0"
1588 | },
1589 | "bin": {
1590 | "semver": "bin/semver.js"
1591 | },
1592 | "engines": {
1593 | "node": ">=10"
1594 | }
1595 | },
1596 | "node_modules/send": {
1597 | "version": "0.19.0",
1598 | "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
1599 | "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
1600 | "dev": true,
1601 | "dependencies": {
1602 | "debug": "2.6.9",
1603 | "depd": "2.0.0",
1604 | "destroy": "1.2.0",
1605 | "encodeurl": "~1.0.2",
1606 | "escape-html": "~1.0.3",
1607 | "etag": "~1.8.1",
1608 | "fresh": "0.5.2",
1609 | "http-errors": "2.0.0",
1610 | "mime": "1.6.0",
1611 | "ms": "2.1.3",
1612 | "on-finished": "2.4.1",
1613 | "range-parser": "~1.2.1",
1614 | "statuses": "2.0.1"
1615 | },
1616 | "engines": {
1617 | "node": ">= 0.8.0"
1618 | }
1619 | },
1620 | "node_modules/send/node_modules/ms": {
1621 | "version": "2.1.3",
1622 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
1623 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
1624 | "dev": true
1625 | },
1626 | "node_modules/send/node_modules/on-finished": {
1627 | "version": "2.4.1",
1628 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
1629 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
1630 | "dev": true,
1631 | "dependencies": {
1632 | "ee-first": "1.1.1"
1633 | },
1634 | "engines": {
1635 | "node": ">= 0.8"
1636 | }
1637 | },
1638 | "node_modules/send/node_modules/statuses": {
1639 | "version": "2.0.1",
1640 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
1641 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
1642 | "dev": true,
1643 | "engines": {
1644 | "node": ">= 0.8"
1645 | }
1646 | },
1647 | "node_modules/serialize-javascript": {
1648 | "version": "6.0.2",
1649 | "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
1650 | "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
1651 | "dev": true,
1652 | "dependencies": {
1653 | "randombytes": "^2.1.0"
1654 | }
1655 | },
1656 | "node_modules/serve-static": {
1657 | "version": "1.16.2",
1658 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz",
1659 | "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==",
1660 | "dev": true,
1661 | "dependencies": {
1662 | "encodeurl": "~2.0.0",
1663 | "escape-html": "~1.0.3",
1664 | "parseurl": "~1.3.3",
1665 | "send": "0.19.0"
1666 | },
1667 | "engines": {
1668 | "node": ">= 0.8.0"
1669 | }
1670 | },
1671 | "node_modules/serve-static/node_modules/encodeurl": {
1672 | "version": "2.0.0",
1673 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
1674 | "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
1675 | "dev": true,
1676 | "engines": {
1677 | "node": ">= 0.8"
1678 | }
1679 | },
1680 | "node_modules/setprototypeof": {
1681 | "version": "1.2.0",
1682 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
1683 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
1684 | "dev": true
1685 | },
1686 | "node_modules/shallow-clone": {
1687 | "version": "3.0.1",
1688 | "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
1689 | "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
1690 | "dev": true,
1691 | "dependencies": {
1692 | "kind-of": "^6.0.2"
1693 | },
1694 | "engines": {
1695 | "node": ">=8"
1696 | }
1697 | },
1698 | "node_modules/shebang-command": {
1699 | "version": "2.0.0",
1700 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
1701 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
1702 | "dev": true,
1703 | "dependencies": {
1704 | "shebang-regex": "^3.0.0"
1705 | },
1706 | "engines": {
1707 | "node": ">=8"
1708 | }
1709 | },
1710 | "node_modules/shebang-regex": {
1711 | "version": "3.0.0",
1712 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
1713 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
1714 | "dev": true,
1715 | "engines": {
1716 | "node": ">=8"
1717 | }
1718 | },
1719 | "node_modules/signal-exit": {
1720 | "version": "4.1.0",
1721 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
1722 | "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
1723 | "dev": true,
1724 | "engines": {
1725 | "node": ">=14"
1726 | },
1727 | "funding": {
1728 | "url": "https://github.com/sponsors/isaacs"
1729 | }
1730 | },
1731 | "node_modules/source-map-support": {
1732 | "version": "0.5.21",
1733 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
1734 | "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
1735 | "dev": true,
1736 | "dependencies": {
1737 | "buffer-from": "^1.0.0",
1738 | "source-map": "^0.6.0"
1739 | }
1740 | },
1741 | "node_modules/source-map-support/node_modules/source-map": {
1742 | "version": "0.6.1",
1743 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
1744 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
1745 | "dev": true,
1746 | "engines": {
1747 | "node": ">=0.10.0"
1748 | }
1749 | },
1750 | "node_modules/statuses": {
1751 | "version": "1.5.0",
1752 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
1753 | "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==",
1754 | "dev": true,
1755 | "engines": {
1756 | "node": ">= 0.6"
1757 | }
1758 | },
1759 | "node_modules/string-width": {
1760 | "version": "5.1.2",
1761 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
1762 | "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
1763 | "dev": true,
1764 | "dependencies": {
1765 | "eastasianwidth": "^0.2.0",
1766 | "emoji-regex": "^9.2.2",
1767 | "strip-ansi": "^7.0.1"
1768 | },
1769 | "engines": {
1770 | "node": ">=12"
1771 | },
1772 | "funding": {
1773 | "url": "https://github.com/sponsors/sindresorhus"
1774 | }
1775 | },
1776 | "node_modules/string-width-cjs": {
1777 | "name": "string-width",
1778 | "version": "4.2.3",
1779 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
1780 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
1781 | "dev": true,
1782 | "dependencies": {
1783 | "emoji-regex": "^8.0.0",
1784 | "is-fullwidth-code-point": "^3.0.0",
1785 | "strip-ansi": "^6.0.1"
1786 | },
1787 | "engines": {
1788 | "node": ">=8"
1789 | }
1790 | },
1791 | "node_modules/string-width-cjs/node_modules/ansi-regex": {
1792 | "version": "5.0.1",
1793 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
1794 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
1795 | "dev": true,
1796 | "engines": {
1797 | "node": ">=8"
1798 | }
1799 | },
1800 | "node_modules/string-width-cjs/node_modules/emoji-regex": {
1801 | "version": "8.0.0",
1802 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
1803 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
1804 | "dev": true
1805 | },
1806 | "node_modules/string-width-cjs/node_modules/strip-ansi": {
1807 | "version": "6.0.1",
1808 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
1809 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
1810 | "dev": true,
1811 | "dependencies": {
1812 | "ansi-regex": "^5.0.1"
1813 | },
1814 | "engines": {
1815 | "node": ">=8"
1816 | }
1817 | },
1818 | "node_modules/strip-ansi": {
1819 | "version": "7.1.0",
1820 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
1821 | "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
1822 | "dev": true,
1823 | "dependencies": {
1824 | "ansi-regex": "^6.0.1"
1825 | },
1826 | "engines": {
1827 | "node": ">=12"
1828 | },
1829 | "funding": {
1830 | "url": "https://github.com/chalk/strip-ansi?sponsor=1"
1831 | }
1832 | },
1833 | "node_modules/strip-ansi-cjs": {
1834 | "name": "strip-ansi",
1835 | "version": "6.0.1",
1836 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
1837 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
1838 | "dev": true,
1839 | "dependencies": {
1840 | "ansi-regex": "^5.0.1"
1841 | },
1842 | "engines": {
1843 | "node": ">=8"
1844 | }
1845 | },
1846 | "node_modules/strip-ansi-cjs/node_modules/ansi-regex": {
1847 | "version": "5.0.1",
1848 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
1849 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
1850 | "dev": true,
1851 | "engines": {
1852 | "node": ">=8"
1853 | }
1854 | },
1855 | "node_modules/supports-preserve-symlinks-flag": {
1856 | "version": "1.0.0",
1857 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
1858 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
1859 | "dev": true,
1860 | "engines": {
1861 | "node": ">= 0.4"
1862 | },
1863 | "funding": {
1864 | "url": "https://github.com/sponsors/ljharb"
1865 | }
1866 | },
1867 | "node_modules/tapable": {
1868 | "version": "2.2.1",
1869 | "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
1870 | "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
1871 | "dev": true,
1872 | "engines": {
1873 | "node": ">=6"
1874 | }
1875 | },
1876 | "node_modules/terser": {
1877 | "version": "5.26.0",
1878 | "resolved": "https://registry.npmjs.org/terser/-/terser-5.26.0.tgz",
1879 | "integrity": "sha512-dytTGoE2oHgbNV9nTzgBEPaqAWvcJNl66VZ0BkJqlvp71IjO8CxdBx/ykCNb47cLnCmCvRZ6ZR0tLkqvZCdVBQ==",
1880 | "dev": true,
1881 | "dependencies": {
1882 | "@jridgewell/source-map": "^0.3.3",
1883 | "acorn": "^8.8.2",
1884 | "commander": "^2.20.0",
1885 | "source-map-support": "~0.5.20"
1886 | },
1887 | "bin": {
1888 | "terser": "bin/terser"
1889 | },
1890 | "engines": {
1891 | "node": ">=10"
1892 | }
1893 | },
1894 | "node_modules/terser-webpack-plugin": {
1895 | "version": "5.3.10",
1896 | "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz",
1897 | "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==",
1898 | "dev": true,
1899 | "dependencies": {
1900 | "@jridgewell/trace-mapping": "^0.3.20",
1901 | "jest-worker": "^27.4.5",
1902 | "schema-utils": "^3.1.1",
1903 | "serialize-javascript": "^6.0.1",
1904 | "terser": "^5.26.0"
1905 | },
1906 | "engines": {
1907 | "node": ">= 10.13.0"
1908 | },
1909 | "funding": {
1910 | "type": "opencollective",
1911 | "url": "https://opencollective.com/webpack"
1912 | },
1913 | "peerDependencies": {
1914 | "webpack": "^5.1.0"
1915 | },
1916 | "peerDependenciesMeta": {
1917 | "@swc/core": {
1918 | "optional": true
1919 | },
1920 | "esbuild": {
1921 | "optional": true
1922 | },
1923 | "uglify-js": {
1924 | "optional": true
1925 | }
1926 | }
1927 | },
1928 | "node_modules/to-regex-range": {
1929 | "version": "5.0.1",
1930 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
1931 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
1932 | "dev": true,
1933 | "dependencies": {
1934 | "is-number": "^7.0.0"
1935 | },
1936 | "engines": {
1937 | "node": ">=8.0"
1938 | }
1939 | },
1940 | "node_modules/toidentifier": {
1941 | "version": "1.0.1",
1942 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
1943 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
1944 | "dev": true,
1945 | "engines": {
1946 | "node": ">=0.6"
1947 | }
1948 | },
1949 | "node_modules/ts-loader": {
1950 | "version": "9.5.1",
1951 | "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz",
1952 | "integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==",
1953 | "dev": true,
1954 | "dependencies": {
1955 | "chalk": "^4.1.0",
1956 | "enhanced-resolve": "^5.0.0",
1957 | "micromatch": "^4.0.0",
1958 | "semver": "^7.3.4",
1959 | "source-map": "^0.7.4"
1960 | },
1961 | "engines": {
1962 | "node": ">=12.0.0"
1963 | },
1964 | "peerDependencies": {
1965 | "typescript": "*",
1966 | "webpack": "^5.0.0"
1967 | }
1968 | },
1969 | "node_modules/ts-loader/node_modules/ansi-styles": {
1970 | "version": "4.3.0",
1971 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
1972 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
1973 | "dev": true,
1974 | "dependencies": {
1975 | "color-convert": "^2.0.1"
1976 | },
1977 | "engines": {
1978 | "node": ">=8"
1979 | },
1980 | "funding": {
1981 | "url": "https://github.com/chalk/ansi-styles?sponsor=1"
1982 | }
1983 | },
1984 | "node_modules/ts-loader/node_modules/chalk": {
1985 | "version": "4.1.2",
1986 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
1987 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
1988 | "dev": true,
1989 | "dependencies": {
1990 | "ansi-styles": "^4.1.0",
1991 | "supports-color": "^7.1.0"
1992 | },
1993 | "engines": {
1994 | "node": ">=10"
1995 | },
1996 | "funding": {
1997 | "url": "https://github.com/chalk/chalk?sponsor=1"
1998 | }
1999 | },
2000 | "node_modules/ts-loader/node_modules/has-flag": {
2001 | "version": "4.0.0",
2002 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
2003 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
2004 | "dev": true,
2005 | "engines": {
2006 | "node": ">=8"
2007 | }
2008 | },
2009 | "node_modules/ts-loader/node_modules/micromatch": {
2010 | "version": "4.0.5",
2011 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
2012 | "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
2013 | "dev": true,
2014 | "dependencies": {
2015 | "braces": "^3.0.2",
2016 | "picomatch": "^2.3.1"
2017 | },
2018 | "engines": {
2019 | "node": ">=8.6"
2020 | }
2021 | },
2022 | "node_modules/ts-loader/node_modules/source-map": {
2023 | "version": "0.7.4",
2024 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
2025 | "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
2026 | "dev": true,
2027 | "engines": {
2028 | "node": ">= 8"
2029 | }
2030 | },
2031 | "node_modules/ts-loader/node_modules/supports-color": {
2032 | "version": "7.2.0",
2033 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
2034 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
2035 | "dev": true,
2036 | "dependencies": {
2037 | "has-flag": "^4.0.0"
2038 | },
2039 | "engines": {
2040 | "node": ">=8"
2041 | }
2042 | },
2043 | "node_modules/tslib": {
2044 | "version": "1.14.1",
2045 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
2046 | "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
2047 | "dev": true
2048 | },
2049 | "node_modules/typescript": {
2050 | "version": "5.2.2",
2051 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
2052 | "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
2053 | "dev": true,
2054 | "bin": {
2055 | "tsc": "bin/tsc",
2056 | "tsserver": "bin/tsserver"
2057 | },
2058 | "engines": {
2059 | "node": ">=14.17"
2060 | }
2061 | },
2062 | "node_modules/undici-types": {
2063 | "version": "5.26.5",
2064 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
2065 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
2066 | "dev": true
2067 | },
2068 | "node_modules/unpipe": {
2069 | "version": "1.0.0",
2070 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
2071 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
2072 | "dev": true,
2073 | "engines": {
2074 | "node": ">= 0.8"
2075 | }
2076 | },
2077 | "node_modules/update-browserslist-db": {
2078 | "version": "1.0.13",
2079 | "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
2080 | "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
2081 | "dev": true,
2082 | "funding": [
2083 | {
2084 | "type": "opencollective",
2085 | "url": "https://opencollective.com/browserslist"
2086 | },
2087 | {
2088 | "type": "tidelift",
2089 | "url": "https://tidelift.com/funding/github/npm/browserslist"
2090 | },
2091 | {
2092 | "type": "github",
2093 | "url": "https://github.com/sponsors/ai"
2094 | }
2095 | ],
2096 | "dependencies": {
2097 | "escalade": "^3.1.1",
2098 | "picocolors": "^1.0.0"
2099 | },
2100 | "bin": {
2101 | "update-browserslist-db": "cli.js"
2102 | },
2103 | "peerDependencies": {
2104 | "browserslist": ">= 4.21.0"
2105 | }
2106 | },
2107 | "node_modules/uri-js": {
2108 | "version": "4.4.1",
2109 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
2110 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
2111 | "dev": true,
2112 | "dependencies": {
2113 | "punycode": "^2.1.0"
2114 | }
2115 | },
2116 | "node_modules/utils-merge": {
2117 | "version": "1.0.1",
2118 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
2119 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
2120 | "dev": true,
2121 | "engines": {
2122 | "node": ">= 0.4.0"
2123 | }
2124 | },
2125 | "node_modules/watchpack": {
2126 | "version": "2.4.2",
2127 | "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz",
2128 | "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==",
2129 | "dev": true,
2130 | "dependencies": {
2131 | "glob-to-regexp": "^0.4.1",
2132 | "graceful-fs": "^4.1.2"
2133 | },
2134 | "engines": {
2135 | "node": ">=10.13.0"
2136 | }
2137 | },
2138 | "node_modules/webpack": {
2139 | "version": "5.94.0",
2140 | "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz",
2141 | "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==",
2142 | "dev": true,
2143 | "dependencies": {
2144 | "@types/estree": "^1.0.5",
2145 | "@webassemblyjs/ast": "^1.12.1",
2146 | "@webassemblyjs/wasm-edit": "^1.12.1",
2147 | "@webassemblyjs/wasm-parser": "^1.12.1",
2148 | "acorn": "^8.7.1",
2149 | "acorn-import-attributes": "^1.9.5",
2150 | "browserslist": "^4.21.10",
2151 | "chrome-trace-event": "^1.0.2",
2152 | "enhanced-resolve": "^5.17.1",
2153 | "es-module-lexer": "^1.2.1",
2154 | "eslint-scope": "5.1.1",
2155 | "events": "^3.2.0",
2156 | "glob-to-regexp": "^0.4.1",
2157 | "graceful-fs": "^4.2.11",
2158 | "json-parse-even-better-errors": "^2.3.1",
2159 | "loader-runner": "^4.2.0",
2160 | "mime-types": "^2.1.27",
2161 | "neo-async": "^2.6.2",
2162 | "schema-utils": "^3.2.0",
2163 | "tapable": "^2.1.1",
2164 | "terser-webpack-plugin": "^5.3.10",
2165 | "watchpack": "^2.4.1",
2166 | "webpack-sources": "^3.2.3"
2167 | },
2168 | "bin": {
2169 | "webpack": "bin/webpack.js"
2170 | },
2171 | "engines": {
2172 | "node": ">=10.13.0"
2173 | },
2174 | "funding": {
2175 | "type": "opencollective",
2176 | "url": "https://opencollective.com/webpack"
2177 | },
2178 | "peerDependenciesMeta": {
2179 | "webpack-cli": {
2180 | "optional": true
2181 | }
2182 | }
2183 | },
2184 | "node_modules/webpack-cli": {
2185 | "version": "5.1.4",
2186 | "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz",
2187 | "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==",
2188 | "dev": true,
2189 | "dependencies": {
2190 | "@discoveryjs/json-ext": "^0.5.0",
2191 | "@webpack-cli/configtest": "^2.1.1",
2192 | "@webpack-cli/info": "^2.0.2",
2193 | "@webpack-cli/serve": "^2.0.5",
2194 | "colorette": "^2.0.14",
2195 | "commander": "^10.0.1",
2196 | "cross-spawn": "^7.0.3",
2197 | "envinfo": "^7.7.3",
2198 | "fastest-levenshtein": "^1.0.12",
2199 | "import-local": "^3.0.2",
2200 | "interpret": "^3.1.1",
2201 | "rechoir": "^0.8.0",
2202 | "webpack-merge": "^5.7.3"
2203 | },
2204 | "bin": {
2205 | "webpack-cli": "bin/cli.js"
2206 | },
2207 | "engines": {
2208 | "node": ">=14.15.0"
2209 | },
2210 | "funding": {
2211 | "type": "opencollective",
2212 | "url": "https://opencollective.com/webpack"
2213 | },
2214 | "peerDependencies": {
2215 | "webpack": "5.x.x"
2216 | },
2217 | "peerDependenciesMeta": {
2218 | "@webpack-cli/generators": {
2219 | "optional": true
2220 | },
2221 | "webpack-bundle-analyzer": {
2222 | "optional": true
2223 | },
2224 | "webpack-dev-server": {
2225 | "optional": true
2226 | }
2227 | }
2228 | },
2229 | "node_modules/webpack-cli/node_modules/commander": {
2230 | "version": "10.0.1",
2231 | "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
2232 | "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
2233 | "dev": true,
2234 | "engines": {
2235 | "node": ">=14"
2236 | }
2237 | },
2238 | "node_modules/webpack-merge": {
2239 | "version": "5.10.0",
2240 | "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz",
2241 | "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==",
2242 | "dev": true,
2243 | "dependencies": {
2244 | "clone-deep": "^4.0.1",
2245 | "flat": "^5.0.2",
2246 | "wildcard": "^2.0.0"
2247 | },
2248 | "engines": {
2249 | "node": ">=10.0.0"
2250 | }
2251 | },
2252 | "node_modules/webpack-sources": {
2253 | "version": "3.2.3",
2254 | "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
2255 | "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
2256 | "dev": true,
2257 | "engines": {
2258 | "node": ">=10.13.0"
2259 | }
2260 | },
2261 | "node_modules/which": {
2262 | "version": "2.0.2",
2263 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
2264 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
2265 | "dev": true,
2266 | "dependencies": {
2267 | "isexe": "^2.0.0"
2268 | },
2269 | "bin": {
2270 | "node-which": "bin/node-which"
2271 | },
2272 | "engines": {
2273 | "node": ">= 8"
2274 | }
2275 | },
2276 | "node_modules/wildcard": {
2277 | "version": "2.0.1",
2278 | "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz",
2279 | "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==",
2280 | "dev": true
2281 | },
2282 | "node_modules/wrap-ansi": {
2283 | "version": "8.1.0",
2284 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
2285 | "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
2286 | "dev": true,
2287 | "dependencies": {
2288 | "ansi-styles": "^6.1.0",
2289 | "string-width": "^5.0.1",
2290 | "strip-ansi": "^7.0.1"
2291 | },
2292 | "engines": {
2293 | "node": ">=12"
2294 | },
2295 | "funding": {
2296 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
2297 | }
2298 | },
2299 | "node_modules/wrap-ansi-cjs": {
2300 | "name": "wrap-ansi",
2301 | "version": "7.0.0",
2302 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
2303 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
2304 | "dev": true,
2305 | "dependencies": {
2306 | "ansi-styles": "^4.0.0",
2307 | "string-width": "^4.1.0",
2308 | "strip-ansi": "^6.0.0"
2309 | },
2310 | "engines": {
2311 | "node": ">=10"
2312 | },
2313 | "funding": {
2314 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
2315 | }
2316 | },
2317 | "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": {
2318 | "version": "5.0.1",
2319 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
2320 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
2321 | "dev": true,
2322 | "engines": {
2323 | "node": ">=8"
2324 | }
2325 | },
2326 | "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
2327 | "version": "4.3.0",
2328 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
2329 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
2330 | "dev": true,
2331 | "dependencies": {
2332 | "color-convert": "^2.0.1"
2333 | },
2334 | "engines": {
2335 | "node": ">=8"
2336 | },
2337 | "funding": {
2338 | "url": "https://github.com/chalk/ansi-styles?sponsor=1"
2339 | }
2340 | },
2341 | "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
2342 | "version": "8.0.0",
2343 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
2344 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
2345 | "dev": true
2346 | },
2347 | "node_modules/wrap-ansi-cjs/node_modules/string-width": {
2348 | "version": "4.2.3",
2349 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
2350 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
2351 | "dev": true,
2352 | "dependencies": {
2353 | "emoji-regex": "^8.0.0",
2354 | "is-fullwidth-code-point": "^3.0.0",
2355 | "strip-ansi": "^6.0.1"
2356 | },
2357 | "engines": {
2358 | "node": ">=8"
2359 | }
2360 | },
2361 | "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": {
2362 | "version": "6.0.1",
2363 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
2364 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
2365 | "dev": true,
2366 | "dependencies": {
2367 | "ansi-regex": "^5.0.1"
2368 | },
2369 | "engines": {
2370 | "node": ">=8"
2371 | }
2372 | },
2373 | "node_modules/yallist": {
2374 | "version": "4.0.0",
2375 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
2376 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
2377 | "dev": true
2378 | }
2379 | }
2380 | }
2381 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-blazor",
3 | "version": "0.1.0",
4 | "description": "React vs. Blazor side by side",
5 | "keywords": [
6 | "React",
7 | "Blazor",
8 | "WebAssembly"
9 | ],
10 | "scripts": {
11 | "build:react": "webpack",
12 | "build:blazor": "dotnet publish src/blazor/BlazorChatApp.csproj -c Release && node blazor-output.js Release",
13 | "build:blazor:docker": "docker run --rm -v $(pwd)/src/blazor:/app mcr.microsoft.com/dotnet/sdk:5.0 dotnet publish -c Release app/BlazorChatApp.csproj && node blazor-output.js Release",
14 | "build:blazor:docker:win": "docker run --rm -v ${pwd}/src/blazor:/app mcr.microsoft.com/dotnet/sdk:5.0 dotnet publish -c Release app/BlazorChatApp.csproj && node blazor-output.js Release",
15 | "build": "npm run build:react && npm run build:blazor",
16 | "start": "node serve.js"
17 | },
18 | "private": true,
19 | "author": "Boyan Mihaylov",
20 | "license": "MIT",
21 | "repository": {
22 | "type": "git",
23 | "url": "https://github.com/boyanio/react-blazor.git"
24 | },
25 | "devDependencies": {
26 | "@types/react": "^18.2.47",
27 | "@types/react-dom": "^18.2.18",
28 | "connect": "^3.7.0",
29 | "connect-modrewrite": "^0.10.2",
30 | "ncp": "^2.0.0",
31 | "rimraf": "^5.0.5",
32 | "serve-static": "^1.16.2",
33 | "ts-loader": "^9.5.1",
34 | "typescript": "^5.2.2",
35 | "webpack": "^5.94.0",
36 | "webpack-cli": "^5.1.4"
37 | },
38 | "dependencies": {
39 | "react": "^18.2.0",
40 | "react-dom": "^18.2.0"
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/serve.js:
--------------------------------------------------------------------------------
1 | const connect = require('connect');
2 | const serveStatic = require('serve-static');
3 | const modRewrite = require('connect-modrewrite');
4 |
5 | const buildDir = `${__dirname}/build`;
6 | const port = 8080;
7 | const setHeaders = (res, path) => {
8 | const ext = path.split('.').pop().toLowerCase();
9 | let contentType;
10 | switch (ext) {
11 | case 'wasm':
12 | contentType = 'application/wasm';
13 | break;
14 |
15 | case 'js':
16 | contentType = 'text/javascript';
17 | break;
18 |
19 | case 'dll':
20 | contentType = 'application/octet-stream';
21 | break;
22 |
23 | case 'html':
24 | case 'css':
25 | contentType = `text/${ext}`;
26 | break;
27 | }
28 |
29 | if (contentType) {
30 | res.setHeader('Content-Type', contentType);
31 | }
32 | };
33 |
34 | console.log(`Serving HTTP on http://localhost:${port}/react-blazor/ ...`);
35 | connect()
36 | .use(modRewrite([
37 | '^/react-blazor/_framework/(.+) /apps/blazor/_framework/$1 [L]',
38 | '^/react-blazor/?(.+) /$1 [L]'
39 | ]))
40 | .use(serveStatic(buildDir, { 'setHeaders': setHeaders }))
41 | .use((req, res, next) => {
42 | const url = req.url;
43 | console.log(url);
44 | next();
45 | })
46 | .listen(port);
--------------------------------------------------------------------------------
/src/blazor/App.razor:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Sorry, there's nothing at this address.
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/blazor/BlazorChatApp.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net5.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/blazor/Core/ChatMessage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace BlazorChatApp.Core
4 | {
5 | public class ChatMessage
6 | {
7 | public DateTime Time { get; set; }
8 |
9 | public string From { get; set; }
10 |
11 | public string Text { get; set; }
12 | }
13 | }
--------------------------------------------------------------------------------
/src/blazor/Core/ChatMessageRepository.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.JSInterop;
2 | using System;
3 | using System.Threading.Tasks;
4 |
5 | namespace BlazorChatApp.Core
6 | {
7 | public class ChatMessageRepository
8 | {
9 | private readonly IJSRuntime _jsRuntime;
10 |
11 | public ChatMessageRepository(IJSRuntime jsRuntime)
12 | {
13 | _jsRuntime = jsRuntime ?? throw new ArgumentNullException(nameof(jsRuntime));
14 | }
15 |
16 | public async Task GetChatMessagesAsync()
17 | {
18 | return await _jsRuntime.InvokeAsync(
19 | "ChatMessageRepository.getChatMessages");
20 |
21 | }
22 |
23 | public async Task AddChatMessageAsync(ChatMessage chatMessage)
24 | {
25 | await _jsRuntime.InvokeAsync(
26 | "ChatMessageRepository.addChatMessage",
27 | chatMessage);
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/src/blazor/Core/TimeUtils.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace BlazorChatApp.Core
4 | {
5 | internal static class TimeUtils
6 | {
7 | internal static string FormatRelativeTime(DateTime date)
8 | {
9 | // Taken from https://stackoverflow.com/a/1248
10 | const int SECOND = 1;
11 | const int MINUTE = 60 * SECOND;
12 | const int HOUR = 60 * MINUTE;
13 | const int DAY = 24 * HOUR;
14 | const int MONTH = 30 * DAY;
15 |
16 | var ts = new TimeSpan(DateTime.UtcNow.Ticks - date.Ticks);
17 | double delta = Math.Abs(ts.TotalSeconds);
18 |
19 | if (delta < 1 * MINUTE)
20 | return ts.Seconds <= 1 ? "1 second ago" : $"{ts.Seconds} seconds ago";
21 |
22 | if (delta < 2 * MINUTE)
23 | return "1 minute ago";
24 |
25 | if (delta < 45 * MINUTE)
26 | return $"{ts.Minutes} minutes ago";
27 |
28 | if (delta < 90 * MINUTE)
29 | return "1 hour ago";
30 |
31 | if (delta < 24 * HOUR)
32 | return $"{ts.Hours} hours ago";
33 |
34 | if (delta < 48 * HOUR)
35 | return "yesterday";
36 |
37 | if (delta < 30 * DAY)
38 | return $"{ts.Days} days ago";
39 |
40 | if (delta < 12 * MONTH)
41 | {
42 | int months = Convert.ToInt32(Math.Floor((double)ts.Days / 30));
43 | return months <= 1 ? "1 month ago" : $"{months} months ago";
44 | }
45 | else
46 | {
47 | int years = Convert.ToInt32(Math.Floor((double)ts.Days / 365));
48 | return years <= 1 ? "1 year ago" : $"{years} years ago";
49 | }
50 | }
51 | }
52 | }
--------------------------------------------------------------------------------
/src/blazor/Pages/Root.razor:
--------------------------------------------------------------------------------
1 | @page "/"
2 |
3 | Blazor chat
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/blazor/Pages/_Imports.razor:
--------------------------------------------------------------------------------
1 | @layout MainLayout
--------------------------------------------------------------------------------
/src/blazor/Program.cs:
--------------------------------------------------------------------------------
1 | using BlazorChatApp.Core;
2 | using System.Threading.Tasks;
3 | using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
4 | using Microsoft.Extensions.DependencyInjection;
5 |
6 | namespace BlazorChatApp
7 | {
8 | public class Program
9 | {
10 | public static async Task Main(string[] args)
11 | {
12 | var builder = WebAssemblyHostBuilder.CreateDefault(args);
13 | builder.RootComponents.Add("#blazor-app");
14 | builder.Services.AddSingleton();
15 |
16 | await builder.Build().RunAsync();
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/blazor/Shared/Chat.razor:
--------------------------------------------------------------------------------
1 | @using System.Timers
2 | @inject ChatMessageRepository ChatMessageRepository
3 |
4 |
5 |
6 | @if (_chatMessages.Length > 0)
7 | {
8 |
9 |
10 | @foreach (var chatMessage in _chatMessages)
11 | {
12 | bool isLeft = _chatMessages[_chatMessages.Length - 1].From.Equals(chatMessage.From);
13 |
14 |
15 |
16 |
17 |
@chatMessage.Text
18 |
@TimeUtils.FormatRelativeTime(chatMessage.Time)
19 |
20 |
21 | }
22 |
23 |
24 | }
25 | else
26 | {
27 |
28 | There aren't any messages yet. Why don't you write one?
29 |
30 | }
31 |
32 |
33 |
34 | @code {
35 | private ChatMessage[] _chatMessages = new ChatMessage[0];
36 | private Timer _timer = new Timer(1000);
37 |
38 | protected override void OnInitialized()
39 | {
40 | _timer.Elapsed += async (sender, args) => await TickAsync();
41 | _timer.Start();
42 | }
43 |
44 | private async Task TickAsync()
45 | {
46 | _chatMessages = (await ChatMessageRepository.GetChatMessagesAsync())
47 | .OrderByDescending(m => m.Time)
48 | .ToArray();
49 | StateHasChanged();
50 | }
51 | }
--------------------------------------------------------------------------------
/src/blazor/Shared/MainLayout.razor:
--------------------------------------------------------------------------------
1 | @inherits LayoutComponentBase
2 |
3 |
--------------------------------------------------------------------------------
/src/blazor/Shared/NewChatMessage.razor:
--------------------------------------------------------------------------------
1 | @inject ChatMessageRepository ChatMessageRepository
2 |
3 |
13 |
14 | @code {
15 | private string newMessage = null;
16 |
17 | private async Task AddChatMessageAsync(MouseEventArgs e)
18 | {
19 | await ChatMessageRepository.AddChatMessageAsync(new ChatMessage
20 | {
21 | Time = DateTime.Now,
22 | From = "Blazor",
23 | Text = newMessage
24 | });
25 | newMessage = null;
26 | }
27 | }
--------------------------------------------------------------------------------
/src/blazor/_Imports.razor:
--------------------------------------------------------------------------------
1 | @using System.Linq
2 | @using System.Net.Http
3 | @using Microsoft.AspNetCore.Components.Forms
4 | @using Microsoft.AspNetCore.Components.Routing
5 | @using Microsoft.AspNetCore.Components.Web
6 | @using Microsoft.JSInterop
7 | @using BlazorChatApp
8 | @using BlazorChatApp.Core
9 | @using BlazorChatApp.Shared
--------------------------------------------------------------------------------
/src/common/ChatMessage.ts:
--------------------------------------------------------------------------------
1 | export interface ChatMessage {
2 | time: Date;
3 | from: string;
4 | text: string;
5 | };
--------------------------------------------------------------------------------
/src/common/ChatMessageRepository.d.ts:
--------------------------------------------------------------------------------
1 | import { ChatMessage } from "./ChatMessage";
2 |
3 | declare const ChatMessageRepository: IChatMessageRepository;
4 |
5 | declare global {
6 | interface Window {
7 | ChatMessageRepository: IChatMessageRepository;
8 | }
9 | }
10 |
11 | interface IChatMessageRepository {
12 | getChatMessages: () => ChatMessage[];
13 | addChatMessage: (chatMessage: ChatMessage) => void;
14 | }
15 |
16 | export = ChatMessageRepository;
--------------------------------------------------------------------------------
/src/common/ChatMessageRepository.ts:
--------------------------------------------------------------------------------
1 | import { ChatMessage } from "./ChatMessage";
2 |
3 | const sessionStorageKey = "chat-messages";
4 |
5 | const getChatMessages =
6 | () => (JSON.parse(sessionStorage.getItem(sessionStorageKey) || "[]"))
7 | .map(x => { from: x.from, text: x.text, time: new Date(Date.parse(x.time)) });
8 |
9 | const chatMessageRepository = {
10 | getChatMessages,
11 | addChatMessage: (chatMessage: ChatMessage) =>
12 | sessionStorage.setItem(sessionStorageKey, JSON.stringify([...getChatMessages(), chatMessage]))
13 | }
14 |
15 | window.ChatMessageRepository = chatMessageRepository;
--------------------------------------------------------------------------------
/src/common/index.ts:
--------------------------------------------------------------------------------
1 | import "./ChatMessageRepository";
--------------------------------------------------------------------------------
/src/react/components/Chat.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { ChatMessage } from "./ChatMessage";
3 | import { ChatMessage as ChatMessageModel } from "../../common/ChatMessage";
4 |
5 | const byTimeDesc = (a: ChatMessageModel, b: ChatMessageModel) =>
6 | b.time.getTime() - a.time.getTime();
7 |
8 | export interface ChatProps {
9 | chatMessages: ChatMessageModel[];
10 | }
11 |
12 | export const Chat = (props: ChatProps) => {
13 | const hasChatMessages = props.chatMessages.length > 0;
14 |
15 | const body = hasChatMessages ?
16 |
17 |
18 | {props.chatMessages
19 | .sort(byTimeDesc)
20 | .map((chatMessage, index) => )}
21 |
22 |
:
23 |
24 | There aren't any messages yet. Why don't you write one?
25 |
;
26 |
27 | return (
28 |
29 |
30 | {body}
31 |
32 |
33 | );
34 | }
--------------------------------------------------------------------------------
/src/react/components/ChatMessage.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { ChatMessage as ChatMessageModel } from "../../common/ChatMessage";
3 | import { formatRelativeTime } from "../core/TimeUtils";
4 |
5 | export interface ChatMessageProps {
6 | isLeft: boolean;
7 | chatMessage: ChatMessageModel;
8 | }
9 |
10 | export const ChatMessage = (props: ChatMessageProps) =>
11 |
12 |
13 |
14 |
{props.chatMessage.text}
15 |
{formatRelativeTime(props.chatMessage.time)}
16 |
17 | ;
--------------------------------------------------------------------------------
/src/react/components/NewChatMessage.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import * as ChatMessageRepository from "ChatMessageRepository";
3 |
4 | interface NewChatMessageState {
5 | newMessage: string;
6 | }
7 |
8 | const createDefaultState: () => NewChatMessageState =
9 | () => ({ newMessage: "" });
10 |
11 | export class NewChatMessage extends React.Component<{}, NewChatMessageState> {
12 |
13 | constructor(props) {
14 | super(props);
15 |
16 | this.state = createDefaultState();
17 | this.handleSubmit = this.handleSubmit.bind(this);
18 | this.handleChange = this.handleChange.bind(this);
19 | }
20 |
21 | render() {
22 | return (
23 |
33 | );
34 | }
35 |
36 | handleChange(event: React.FormEvent) {
37 | this.setState({ newMessage: event.currentTarget.value });
38 | }
39 |
40 | handleSubmit() {
41 | ChatMessageRepository.addChatMessage({ from: 'React', time: new Date(), text: this.state.newMessage });
42 | this.setState(createDefaultState());
43 | }
44 | }
--------------------------------------------------------------------------------
/src/react/components/Root.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { NewChatMessage } from "./NewChatMessage";
3 | import { Chat } from "./Chat";
4 | import { ChatMessage as ChatMessageModel } from "../../common/ChatMessage";
5 | import * as ChatMessageRepository from "ChatMessageRepository";
6 |
7 | interface RootState {
8 | chatMessages: ChatMessageModel[];
9 | }
10 |
11 | export class Root extends React.Component<{}, RootState> {
12 |
13 | constructor(props) {
14 | super(props);
15 |
16 | this.state = { chatMessages: [] };
17 | }
18 |
19 | componentDidMount() {
20 | setInterval(() => {
21 | this.setState({
22 | chatMessages: ChatMessageRepository.getChatMessages()
23 | });
24 | }, 1000);
25 | }
26 |
27 | render() {
28 | return (
29 |
30 |
React chat
31 |
32 |
33 |
34 |
35 |
36 | );
37 | }
38 | }
--------------------------------------------------------------------------------
/src/react/core/TimeUtils.ts:
--------------------------------------------------------------------------------
1 | export const formatRelativeTime = (date: Date) => {
2 | const seconds = Math.floor((new Date().getTime() - date.getTime()) / 1000);
3 | let interval = Math.floor(seconds / 31536000);
4 |
5 | if (interval > 1)
6 | return `${interval} years ago`;
7 |
8 | interval = Math.floor(seconds / 2592000);
9 | if (interval > 1)
10 | return `${interval} months ago`;
11 |
12 | interval = Math.floor(seconds / 86400);
13 | if (interval > 1)
14 | return `${interval} days ago`;
15 |
16 | interval = Math.floor(seconds / 3600);
17 | if (interval > 1)
18 | return `${interval} hours ago`;
19 |
20 | interval = Math.floor(seconds / 60);
21 | if (interval >= 1)
22 | return `${interval} minute${interval === 1 ? '' : 's'} ago`;
23 |
24 | return `${(Math.floor(seconds) || 1)} seconds ago`;
25 | }
--------------------------------------------------------------------------------
/src/react/index.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import * as ReactDOM from "react-dom";
3 |
4 | import { Root } from "./components/Root";
5 |
6 | ReactDOM.render(
7 | ,
8 | document.getElementById("react-app")
9 | );
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "jsx": "react-jsx",
5 | "lib": ["DOM", "ES2022"],
6 | "moduleResolution": "node",
7 | "baseUrl": ".",
8 | "paths": {
9 | "ChatMessageRepository": [
10 | "src/common/ChatMessageRepository.d"
11 | ]
12 | }
13 | },
14 | "exclude": [
15 | "node_modules"
16 | ],
17 | "include": [
18 | "./src/react/**/*",
19 | "./src/common/**/*",
20 | ]
21 | }
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const baseConfig = {
2 | mode: "production",
3 | devtool: "source-map",
4 | resolve: {
5 | extensions: [".ts", ".tsx", ".js"]
6 | },
7 | module: {
8 | rules: [
9 | { test: /\.tsx?$/, loader: "ts-loader" },
10 | ]
11 | }
12 | };
13 |
14 | const commonConfig = Object.assign({}, baseConfig, {
15 | name: "common",
16 | entry: "./src/common/index.ts",
17 | output: {
18 | filename: "common.js",
19 | path: __dirname + "/build/apps"
20 | },
21 | });
22 |
23 | const reactConfig = Object.assign({}, baseConfig, {
24 | name: "react",
25 | entry: "./src/react/index.tsx",
26 | output: {
27 | filename: "react-app.js",
28 | path: __dirname + "/build/apps/react"
29 | },
30 | externals: {
31 | "react": "React",
32 | "react-dom": "ReactDOM",
33 | "ChatMessageRepository": "ChatMessageRepository"
34 | }
35 | });
36 |
37 | module.exports = [commonConfig, reactConfig];
--------------------------------------------------------------------------------