├── .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 | Fork me on GitHub 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 |
4 |
5 | @Body 6 |
7 |
-------------------------------------------------------------------------------- /src/blazor/Shared/NewChatMessage.razor: -------------------------------------------------------------------------------- 1 | @inject ChatMessageRepository ChatMessageRepository 2 | 3 |
4 |
5 |
6 | 7 |
8 |
9 | 10 |
11 |
12 |
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 |
    24 |
    25 |
    26 | 27 |
    28 |
    29 | 30 |
    31 |
    32 |
    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]; --------------------------------------------------------------------------------