├── .github └── FUNDING.yml ├── .gitignore ├── CHANGELOG.md ├── README.md ├── build.js ├── package-lock.json ├── package.json ├── src ├── dateTimeUtilities.ts ├── ical.d.ts └── index.ts ├── test └── test.mw └── tsconfig.json /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | 2 | github: kochrt -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | lib 4 | view-templates 5 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 1.2.4 2 | - Bump parser and calendar 3 | 4 | ## 1.2.3 5 | 6 | - Update timeline 7 | 8 | ## 1.2.2 9 | 10 | - Bump deps 11 | 12 | ## 1.2.1 13 | - Very basic ical -> markwhen conversion 14 | 15 | Usage: `mw calendar.ical` -> outputs calendar.mw 16 | 17 | ## 1.2.0 18 | - Bump parser 19 | 20 | ## 1.1.2 21 | 22 | - Allow documents to specify a `preferredView` in their header that will be abided by if `outputType` is not specified 23 | 24 | ## 1.1.1 25 | 26 | - Fix watch (we weren't rereading the file) 27 | - Default watch to timeline view 28 | 29 | ## 1.1.0 30 | 31 | - Support for watching files (resume) 32 | 33 | ## 1.0.1 34 | 35 | - Support live serving with sockets 36 | - Fix https://github.com/mark-when/markwhen/issues/107 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # @markwhen/mw 2 | 3 | `mw` is the [markwhen](https://docs.markwhen.com) command line interface (CLI). You can use it to parse markwhen files and optionally render a view of it (timeline+gantt/calendar/resume). 4 | 5 | All html output is self-contained; js and css are inlined and there are no external scripts. 6 | 7 | ## Installation 8 | 9 | ```sh 10 | npm i -g @markwhen/mw 11 | ``` 12 | 13 | ## Usage 14 | 15 | ### Output HTML 16 | 17 | ```sh 18 | mw [serve] [] [-o ] [-d ] [-p ] [-s ] 19 | ``` 20 | 21 | | Option | Description | 22 | | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 23 | | `serve` | If provided, will start a server at the specified `port` and watch the `input_file` for changes | 24 | | `outputType` | one of `json` \| `timeline` \| `calendar` \| `resume` | 25 | | `destination` | File to write to. Output type can be inferred from the filename if `outputType` is not specified; i.e., files ending in `timeline.html` will produce the timeline view, files ending in `json` will produce the raw parse output. | 26 | | `port` | If serving, port to serve from | 27 | | `socketPort` | If serving, socket port to serve from | 28 | 29 | Parse markwhen document and output json: 30 | 31 | ```sh 32 | mw project.mw 33 | # -> outputs timeline.mw.json 34 | ``` 35 | 36 | Render a timeline view: 37 | 38 | ```sh 39 | mw my_markwhen_file.mw timeline.html 40 | # -> outputs timeline.html (timeline+gantt view) 41 | ``` 42 | 43 | Render a calendar view: 44 | 45 | ```sh 46 | mw ThingsToDo.mw ThingsToDo-calendar.html 47 | # -> outputs ThingsToDo-calendar.html (calendar view - inferred from the filename) 48 | ``` 49 | 50 | ### Start a server and watch file 51 | 52 | `mw serve ` will start a server and reflect changes to the input file. 53 | 54 | Watch `projects.mw` and get immediate updates in `localhost:3000`: 55 | 56 | ```sh 57 | mw serve projects.mw -o calendar 58 | ``` -------------------------------------------------------------------------------- /build.js: -------------------------------------------------------------------------------- 1 | import { cpSync } from "fs"; 2 | 3 | cpSync( 4 | "node_modules/@markwhen/timeline/dist/index.html", 5 | "view-templates/timeline.html" 6 | ); 7 | cpSync( 8 | "node_modules/@markwhen/resume/dist/index.html", 9 | "view-templates/resume.html" 10 | ); 11 | cpSync( 12 | "node_modules/@markwhen/calendar/dist/index.html", 13 | "view-templates/calendar.html" 14 | ); 15 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@markwhen/mw", 3 | "version": "1.2.3", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "@markwhen/mw", 9 | "version": "1.2.3", 10 | "license": "MIT", 11 | "dependencies": { 12 | "@markwhen/calendar": "^1.3.4", 13 | "@markwhen/parser": "^0.10.14", 14 | "@markwhen/resume": "^1.1.0", 15 | "@markwhen/timeline": "^1.3.0", 16 | "@nuxt/devalue": "^2.0.2", 17 | "express": "^4.18.2", 18 | "ical.js": "^1.5.0", 19 | "node-html-parser": "^6.1.10", 20 | "ws": "^8.14.2", 21 | "yargs": "^17.7.2" 22 | }, 23 | "bin": { 24 | "mw": "lib/index.js" 25 | }, 26 | "devDependencies": { 27 | "@types/express": "^4.17.17", 28 | "@types/luxon": "^3.3.2", 29 | "@types/node": "^18.15.5", 30 | "@types/ws": "^8.5.4", 31 | "@types/yargs": "^17.0.23", 32 | "esbuild": "^0.17.12", 33 | "tsc-watch": "^6.0.0", 34 | "typescript": "^5.2.2" 35 | } 36 | }, 37 | "node_modules/@babel/parser": { 38 | "version": "7.22.16", 39 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.16.tgz", 40 | "integrity": "sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==", 41 | "bin": { 42 | "parser": "bin/babel-parser.js" 43 | }, 44 | "engines": { 45 | "node": ">=6.0.0" 46 | } 47 | }, 48 | "node_modules/@esbuild/android-arm": { 49 | "version": "0.17.12", 50 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.12.tgz", 51 | "integrity": "sha512-E/sgkvwoIfj4aMAPL2e35VnUJspzVYl7+M1B2cqeubdBhADV4uPon0KCc8p2G+LqSJ6i8ocYPCqY3A4GGq0zkQ==", 52 | "cpu": [ 53 | "arm" 54 | ], 55 | "dev": true, 56 | "optional": true, 57 | "os": [ 58 | "android" 59 | ], 60 | "engines": { 61 | "node": ">=12" 62 | } 63 | }, 64 | "node_modules/@esbuild/android-arm64": { 65 | "version": "0.17.12", 66 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.12.tgz", 67 | "integrity": "sha512-WQ9p5oiXXYJ33F2EkE3r0FRDFVpEdcDiwNX3u7Xaibxfx6vQE0Sb8ytrfQsA5WO6kDn6mDfKLh6KrPBjvkk7xA==", 68 | "cpu": [ 69 | "arm64" 70 | ], 71 | "dev": true, 72 | "optional": true, 73 | "os": [ 74 | "android" 75 | ], 76 | "engines": { 77 | "node": ">=12" 78 | } 79 | }, 80 | "node_modules/@esbuild/android-x64": { 81 | "version": "0.17.12", 82 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.12.tgz", 83 | "integrity": "sha512-m4OsaCr5gT+se25rFPHKQXARMyAehHTQAz4XX1Vk3d27VtqiX0ALMBPoXZsGaB6JYryCLfgGwUslMqTfqeLU0w==", 84 | "cpu": [ 85 | "x64" 86 | ], 87 | "dev": true, 88 | "optional": true, 89 | "os": [ 90 | "android" 91 | ], 92 | "engines": { 93 | "node": ">=12" 94 | } 95 | }, 96 | "node_modules/@esbuild/darwin-arm64": { 97 | "version": "0.17.12", 98 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.12.tgz", 99 | "integrity": "sha512-O3GCZghRIx+RAN0NDPhyyhRgwa19MoKlzGonIb5hgTj78krqp9XZbYCvFr9N1eUxg0ZQEpiiZ4QvsOQwBpP+lg==", 100 | "cpu": [ 101 | "arm64" 102 | ], 103 | "dev": true, 104 | "optional": true, 105 | "os": [ 106 | "darwin" 107 | ], 108 | "engines": { 109 | "node": ">=12" 110 | } 111 | }, 112 | "node_modules/@esbuild/darwin-x64": { 113 | "version": "0.17.12", 114 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.12.tgz", 115 | "integrity": "sha512-5D48jM3tW27h1qjaD9UNRuN+4v0zvksqZSPZqeSWggfMlsVdAhH3pwSfQIFJwcs9QJ9BRibPS4ViZgs3d2wsCA==", 116 | "cpu": [ 117 | "x64" 118 | ], 119 | "dev": true, 120 | "optional": true, 121 | "os": [ 122 | "darwin" 123 | ], 124 | "engines": { 125 | "node": ">=12" 126 | } 127 | }, 128 | "node_modules/@esbuild/freebsd-arm64": { 129 | "version": "0.17.12", 130 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.12.tgz", 131 | "integrity": "sha512-OWvHzmLNTdF1erSvrfoEBGlN94IE6vCEaGEkEH29uo/VoONqPnoDFfShi41Ew+yKimx4vrmmAJEGNoyyP+OgOQ==", 132 | "cpu": [ 133 | "arm64" 134 | ], 135 | "dev": true, 136 | "optional": true, 137 | "os": [ 138 | "freebsd" 139 | ], 140 | "engines": { 141 | "node": ">=12" 142 | } 143 | }, 144 | "node_modules/@esbuild/freebsd-x64": { 145 | "version": "0.17.12", 146 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.12.tgz", 147 | "integrity": "sha512-A0Xg5CZv8MU9xh4a+7NUpi5VHBKh1RaGJKqjxe4KG87X+mTjDE6ZvlJqpWoeJxgfXHT7IMP9tDFu7IZ03OtJAw==", 148 | "cpu": [ 149 | "x64" 150 | ], 151 | "dev": true, 152 | "optional": true, 153 | "os": [ 154 | "freebsd" 155 | ], 156 | "engines": { 157 | "node": ">=12" 158 | } 159 | }, 160 | "node_modules/@esbuild/linux-arm": { 161 | "version": "0.17.12", 162 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.12.tgz", 163 | "integrity": "sha512-WsHyJ7b7vzHdJ1fv67Yf++2dz3D726oO3QCu8iNYik4fb5YuuReOI9OtA+n7Mk0xyQivNTPbl181s+5oZ38gyA==", 164 | "cpu": [ 165 | "arm" 166 | ], 167 | "dev": true, 168 | "optional": true, 169 | "os": [ 170 | "linux" 171 | ], 172 | "engines": { 173 | "node": ">=12" 174 | } 175 | }, 176 | "node_modules/@esbuild/linux-arm64": { 177 | "version": "0.17.12", 178 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.12.tgz", 179 | "integrity": "sha512-cK3AjkEc+8v8YG02hYLQIQlOznW+v9N+OI9BAFuyqkfQFR+DnDLhEM5N8QRxAUz99cJTo1rLNXqRrvY15gbQUg==", 180 | "cpu": [ 181 | "arm64" 182 | ], 183 | "dev": true, 184 | "optional": true, 185 | "os": [ 186 | "linux" 187 | ], 188 | "engines": { 189 | "node": ">=12" 190 | } 191 | }, 192 | "node_modules/@esbuild/linux-ia32": { 193 | "version": "0.17.12", 194 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.12.tgz", 195 | "integrity": "sha512-jdOBXJqcgHlah/nYHnj3Hrnl9l63RjtQ4vn9+bohjQPI2QafASB5MtHAoEv0JQHVb/xYQTFOeuHnNYE1zF7tYw==", 196 | "cpu": [ 197 | "ia32" 198 | ], 199 | "dev": true, 200 | "optional": true, 201 | "os": [ 202 | "linux" 203 | ], 204 | "engines": { 205 | "node": ">=12" 206 | } 207 | }, 208 | "node_modules/@esbuild/linux-loong64": { 209 | "version": "0.17.12", 210 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.12.tgz", 211 | "integrity": "sha512-GTOEtj8h9qPKXCyiBBnHconSCV9LwFyx/gv3Phw0pa25qPYjVuuGZ4Dk14bGCfGX3qKF0+ceeQvwmtI+aYBbVA==", 212 | "cpu": [ 213 | "loong64" 214 | ], 215 | "dev": true, 216 | "optional": true, 217 | "os": [ 218 | "linux" 219 | ], 220 | "engines": { 221 | "node": ">=12" 222 | } 223 | }, 224 | "node_modules/@esbuild/linux-mips64el": { 225 | "version": "0.17.12", 226 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.12.tgz", 227 | "integrity": "sha512-o8CIhfBwKcxmEENOH9RwmUejs5jFiNoDw7YgS0EJTF6kgPgcqLFjgoc5kDey5cMHRVCIWc6kK2ShUePOcc7RbA==", 228 | "cpu": [ 229 | "mips64el" 230 | ], 231 | "dev": true, 232 | "optional": true, 233 | "os": [ 234 | "linux" 235 | ], 236 | "engines": { 237 | "node": ">=12" 238 | } 239 | }, 240 | "node_modules/@esbuild/linux-ppc64": { 241 | "version": "0.17.12", 242 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.12.tgz", 243 | "integrity": "sha512-biMLH6NR/GR4z+ap0oJYb877LdBpGac8KfZoEnDiBKd7MD/xt8eaw1SFfYRUeMVx519kVkAOL2GExdFmYnZx3A==", 244 | "cpu": [ 245 | "ppc64" 246 | ], 247 | "dev": true, 248 | "optional": true, 249 | "os": [ 250 | "linux" 251 | ], 252 | "engines": { 253 | "node": ">=12" 254 | } 255 | }, 256 | "node_modules/@esbuild/linux-riscv64": { 257 | "version": "0.17.12", 258 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.12.tgz", 259 | "integrity": "sha512-jkphYUiO38wZGeWlfIBMB72auOllNA2sLfiZPGDtOBb1ELN8lmqBrlMiucgL8awBw1zBXN69PmZM6g4yTX84TA==", 260 | "cpu": [ 261 | "riscv64" 262 | ], 263 | "dev": true, 264 | "optional": true, 265 | "os": [ 266 | "linux" 267 | ], 268 | "engines": { 269 | "node": ">=12" 270 | } 271 | }, 272 | "node_modules/@esbuild/linux-s390x": { 273 | "version": "0.17.12", 274 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.12.tgz", 275 | "integrity": "sha512-j3ucLdeY9HBcvODhCY4b+Ds3hWGO8t+SAidtmWu/ukfLLG/oYDMaA+dnugTVAg5fnUOGNbIYL9TOjhWgQB8W5g==", 276 | "cpu": [ 277 | "s390x" 278 | ], 279 | "dev": true, 280 | "optional": true, 281 | "os": [ 282 | "linux" 283 | ], 284 | "engines": { 285 | "node": ">=12" 286 | } 287 | }, 288 | "node_modules/@esbuild/linux-x64": { 289 | "version": "0.17.12", 290 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.12.tgz", 291 | "integrity": "sha512-uo5JL3cgaEGotaqSaJdRfFNSCUJOIliKLnDGWaVCgIKkHxwhYMm95pfMbWZ9l7GeW9kDg0tSxcy9NYdEtjwwmA==", 292 | "cpu": [ 293 | "x64" 294 | ], 295 | "dev": true, 296 | "optional": true, 297 | "os": [ 298 | "linux" 299 | ], 300 | "engines": { 301 | "node": ">=12" 302 | } 303 | }, 304 | "node_modules/@esbuild/netbsd-x64": { 305 | "version": "0.17.12", 306 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.12.tgz", 307 | "integrity": "sha512-DNdoRg8JX+gGsbqt2gPgkgb00mqOgOO27KnrWZtdABl6yWTST30aibGJ6geBq3WM2TIeW6COs5AScnC7GwtGPg==", 308 | "cpu": [ 309 | "x64" 310 | ], 311 | "dev": true, 312 | "optional": true, 313 | "os": [ 314 | "netbsd" 315 | ], 316 | "engines": { 317 | "node": ">=12" 318 | } 319 | }, 320 | "node_modules/@esbuild/openbsd-x64": { 321 | "version": "0.17.12", 322 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.12.tgz", 323 | "integrity": "sha512-aVsENlr7B64w8I1lhHShND5o8cW6sB9n9MUtLumFlPhG3elhNWtE7M1TFpj3m7lT3sKQUMkGFjTQBrvDDO1YWA==", 324 | "cpu": [ 325 | "x64" 326 | ], 327 | "dev": true, 328 | "optional": true, 329 | "os": [ 330 | "openbsd" 331 | ], 332 | "engines": { 333 | "node": ">=12" 334 | } 335 | }, 336 | "node_modules/@esbuild/sunos-x64": { 337 | "version": "0.17.12", 338 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.12.tgz", 339 | "integrity": "sha512-qbHGVQdKSwi0JQJuZznS4SyY27tYXYF0mrgthbxXrZI3AHKuRvU+Eqbg/F0rmLDpW/jkIZBlCO1XfHUBMNJ1pg==", 340 | "cpu": [ 341 | "x64" 342 | ], 343 | "dev": true, 344 | "optional": true, 345 | "os": [ 346 | "sunos" 347 | ], 348 | "engines": { 349 | "node": ">=12" 350 | } 351 | }, 352 | "node_modules/@esbuild/win32-arm64": { 353 | "version": "0.17.12", 354 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.12.tgz", 355 | "integrity": "sha512-zsCp8Ql+96xXTVTmm6ffvoTSZSV2B/LzzkUXAY33F/76EajNw1m+jZ9zPfNJlJ3Rh4EzOszNDHsmG/fZOhtqDg==", 356 | "cpu": [ 357 | "arm64" 358 | ], 359 | "dev": true, 360 | "optional": true, 361 | "os": [ 362 | "win32" 363 | ], 364 | "engines": { 365 | "node": ">=12" 366 | } 367 | }, 368 | "node_modules/@esbuild/win32-ia32": { 369 | "version": "0.17.12", 370 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.12.tgz", 371 | "integrity": "sha512-FfrFjR4id7wcFYOdqbDfDET3tjxCozUgbqdkOABsSFzoZGFC92UK7mg4JKRc/B3NNEf1s2WHxJ7VfTdVDPN3ng==", 372 | "cpu": [ 373 | "ia32" 374 | ], 375 | "dev": true, 376 | "optional": true, 377 | "os": [ 378 | "win32" 379 | ], 380 | "engines": { 381 | "node": ">=12" 382 | } 383 | }, 384 | "node_modules/@esbuild/win32-x64": { 385 | "version": "0.17.12", 386 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.12.tgz", 387 | "integrity": "sha512-JOOxw49BVZx2/5tW3FqkdjSD/5gXYeVGPDcB0lvap0gLQshkh1Nyel1QazC+wNxus3xPlsYAgqU1BUmrmCvWtw==", 388 | "cpu": [ 389 | "x64" 390 | ], 391 | "dev": true, 392 | "optional": true, 393 | "os": [ 394 | "win32" 395 | ], 396 | "engines": { 397 | "node": ">=12" 398 | } 399 | }, 400 | "node_modules/@fullcalendar/core": { 401 | "version": "6.1.9", 402 | "resolved": "https://registry.npmjs.org/@fullcalendar/core/-/core-6.1.9.tgz", 403 | "integrity": "sha512-eeG+z9BWerdsU9Ac6j16rpYpPnE0wxtnEHiHrh/u/ADbGTR3hCOjCD9PxQOfhOTHbWOVs7JQunGcksSPu5WZBQ==", 404 | "dependencies": { 405 | "preact": "~10.12.1" 406 | } 407 | }, 408 | "node_modules/@fullcalendar/daygrid": { 409 | "version": "6.1.9", 410 | "resolved": "https://registry.npmjs.org/@fullcalendar/daygrid/-/daygrid-6.1.9.tgz", 411 | "integrity": "sha512-o/6joH/7lmVHXAkbaa/tUbzWYnGp/LgfdiFyYPkqQbjKEeivNZWF1WhHqFbhx0zbFONSHtrvkjY2bjr+Ef2quQ==", 412 | "peerDependencies": { 413 | "@fullcalendar/core": "~6.1.9" 414 | } 415 | }, 416 | "node_modules/@fullcalendar/interaction": { 417 | "version": "6.1.9", 418 | "resolved": "https://registry.npmjs.org/@fullcalendar/interaction/-/interaction-6.1.9.tgz", 419 | "integrity": "sha512-I3FGnv0kKZpIwujg3HllbKrciNjTqeTYy3oJG226oAn7lV6wnrrDYMmuGmA0jPJAGN46HKrQqKN7ItxQRDec4Q==", 420 | "peerDependencies": { 421 | "@fullcalendar/core": "~6.1.9" 422 | } 423 | }, 424 | "node_modules/@fullcalendar/multimonth": { 425 | "version": "6.1.9", 426 | "resolved": "https://registry.npmjs.org/@fullcalendar/multimonth/-/multimonth-6.1.9.tgz", 427 | "integrity": "sha512-YpH1NL6RzdM1wO2nFJ3pNMo9xhd6i2WuE+e7SnGi7q1lO+ZZ77h5Fja5JKcpuIQUFHpi+m6vTzihIV8DT44NnQ==", 428 | "dependencies": { 429 | "@fullcalendar/daygrid": "~6.1.9" 430 | }, 431 | "peerDependencies": { 432 | "@fullcalendar/core": "~6.1.9" 433 | } 434 | }, 435 | "node_modules/@fullcalendar/react": { 436 | "version": "6.1.9", 437 | "resolved": "https://registry.npmjs.org/@fullcalendar/react/-/react-6.1.9.tgz", 438 | "integrity": "sha512-ioxu0V++pYz2u/N1LL1V8DkMyiKGRun0gMAll2tQz3Kzi3r9pTwncGKRb1zO8h0e+TrInU08ywk/l5lBwp7eog==", 439 | "peerDependencies": { 440 | "@fullcalendar/core": "~6.1.9", 441 | "react": "^16.7.0 || ^17 || ^18", 442 | "react-dom": "^16.7.0 || ^17 || ^18" 443 | } 444 | }, 445 | "node_modules/@fullcalendar/timegrid": { 446 | "version": "6.1.9", 447 | "resolved": "https://registry.npmjs.org/@fullcalendar/timegrid/-/timegrid-6.1.9.tgz", 448 | "integrity": "sha512-le7UV05wVE1Trdr054kgJXTwa+A1pEI8nlCBnPWdcyrL+dTLoPvQ4AWEVCnV7So+4zRYaCqnqGXfCJsj0RQa0g==", 449 | "dependencies": { 450 | "@fullcalendar/daygrid": "~6.1.9" 451 | }, 452 | "peerDependencies": { 453 | "@fullcalendar/core": "~6.1.9" 454 | } 455 | }, 456 | "node_modules/@jridgewell/sourcemap-codec": { 457 | "version": "1.4.15", 458 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", 459 | "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" 460 | }, 461 | "node_modules/@markwhen/calendar": { 462 | "version": "1.3.4", 463 | "resolved": "https://registry.npmjs.org/@markwhen/calendar/-/calendar-1.3.4.tgz", 464 | "integrity": "sha512-yWDsAlFGNuetW7USBN8mf8t7f4kMNkLNDQ0M1NWcLvi71xTYMeZmi7Xk3NeRyZ3wqikW/nntVd36Ceig4enqnA==", 465 | "dependencies": { 466 | "@fullcalendar/core": "^6.1.9", 467 | "@fullcalendar/daygrid": "^6.1.9", 468 | "@fullcalendar/interaction": "^6.1.9", 469 | "@fullcalendar/multimonth": "^6.1.9", 470 | "@fullcalendar/react": "^6.1.9", 471 | "@fullcalendar/timegrid": "^6.1.9", 472 | "@markwhen/parser": "^0.10.14", 473 | "@markwhen/view-client": "^1.4.3", 474 | "immer": "^10.0.2", 475 | "react": "^18.2.0", 476 | "react-dom": "^18.2.0", 477 | "zustand": "^4.4.1" 478 | } 479 | }, 480 | "node_modules/@markwhen/calendar/node_modules/immer": { 481 | "version": "10.0.2", 482 | "resolved": "https://registry.npmjs.org/immer/-/immer-10.0.2.tgz", 483 | "integrity": "sha512-Rx3CqeqQ19sxUtYV9CU911Vhy8/721wRFnJv3REVGWUmoAcIwzifTsdmJte/MV+0/XpM35LZdQMBGkRIoLPwQA==", 484 | "funding": { 485 | "type": "opencollective", 486 | "url": "https://opencollective.com/immer" 487 | } 488 | }, 489 | "node_modules/@markwhen/parser": { 490 | "version": "0.10.14", 491 | "resolved": "https://registry.npmjs.org/@markwhen/parser/-/parser-0.10.14.tgz", 492 | "integrity": "sha512-g2oK0LovtqhpPbFeR4NGq25uPb9bk3XyJ+tEI3sOa5W4yuKTdzz8/ZnXTDHC/CMGiOI2ug8dgvj2d9LnpNOTXQ==", 493 | "dependencies": { 494 | "ical.js": "^1.5.0", 495 | "lru-cache": "^7.14.1", 496 | "luxon": "^3.3.0", 497 | "yaml": "^2.2.1" 498 | } 499 | }, 500 | "node_modules/@markwhen/resume": { 501 | "version": "1.1.0", 502 | "resolved": "https://registry.npmjs.org/@markwhen/resume/-/resume-1.1.0.tgz", 503 | "integrity": "sha512-MJ3HIRAPsKcJ6YFp0Zjb4ln+30Y929QlcDt+e0CLX8OtEFBvmCEIW4jzdQWf6HCveMXz2v5Oz6tMhJRKBtZtwA==", 504 | "dependencies": { 505 | "@markwhen/parser": "^0.7.0", 506 | "@markwhen/view-client": "^1.2.0", 507 | "@vueuse/core": "^9.13.0", 508 | "@vueuse/integrations": "^9.13.0", 509 | "immer": "^9.0.18", 510 | "luxon": "^3.3.0", 511 | "pinia": "^2.0.33", 512 | "vue": "^3.2.45" 513 | } 514 | }, 515 | "node_modules/@markwhen/resume/node_modules/@markwhen/parser": { 516 | "version": "0.7.0", 517 | "resolved": "https://registry.npmjs.org/@markwhen/parser/-/parser-0.7.0.tgz", 518 | "integrity": "sha512-tS0mhQguv7RbQpHGMYS4R5Yz9gc4wQL4MDD1zUiAaBVXZ9eDRZO60RxgGSvA7oKwQiooRsVThlx5R+fAG1fHAQ==", 519 | "dependencies": { 520 | "lru-cache": "^7.14.1", 521 | "luxon": "^3.3.0", 522 | "yaml": "^2.2.1" 523 | } 524 | }, 525 | "node_modules/@markwhen/timeline": { 526 | "version": "1.3.0", 527 | "resolved": "https://registry.npmjs.org/@markwhen/timeline/-/timeline-1.3.0.tgz", 528 | "integrity": "sha512-zbSGhuG9QBPKu/Rxw0Gc/gD/ho5E16IZ6LO1RWuE+RzjSwGcSM7AhWV0WVlK37x3oIHyH1YPtkVOhlyLye18sA==", 529 | "dependencies": { 530 | "@markwhen/parser": "^0.10.8", 531 | "@squadette/hammerjs": "^2.1.0-pre3", 532 | "@vueuse/core": "^10.4.1", 533 | "@vueuse/integrations": "^10.4.1", 534 | "immer": "^10.0.2", 535 | "luxon": "^3.4.3", 536 | "pinia": "^2.1.6", 537 | "vue": "^3.3.4", 538 | "vue-router": "^4.2.4" 539 | } 540 | }, 541 | "node_modules/@markwhen/timeline/node_modules/@types/web-bluetooth": { 542 | "version": "0.0.17", 543 | "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.17.tgz", 544 | "integrity": "sha512-4p9vcSmxAayx72yn70joFoL44c9MO/0+iVEBIQXe3v2h2SiAsEIo/G5v6ObFWvNKRFjbrVadNf9LqEEZeQPzdA==" 545 | }, 546 | "node_modules/@markwhen/timeline/node_modules/@vueuse/core": { 547 | "version": "10.4.1", 548 | "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.4.1.tgz", 549 | "integrity": "sha512-DkHIfMIoSIBjMgRRvdIvxsyboRZQmImofLyOHADqiVbQVilP8VVHDhBX2ZqoItOgu7dWa8oXiNnScOdPLhdEXg==", 550 | "dependencies": { 551 | "@types/web-bluetooth": "^0.0.17", 552 | "@vueuse/metadata": "10.4.1", 553 | "@vueuse/shared": "10.4.1", 554 | "vue-demi": ">=0.14.5" 555 | }, 556 | "funding": { 557 | "url": "https://github.com/sponsors/antfu" 558 | } 559 | }, 560 | "node_modules/@markwhen/timeline/node_modules/@vueuse/integrations": { 561 | "version": "10.4.1", 562 | "resolved": "https://registry.npmjs.org/@vueuse/integrations/-/integrations-10.4.1.tgz", 563 | "integrity": "sha512-uRBPyG5Lxoh1A/J+boiioPT3ELEAPEo4t8W6Mr4yTKIQBeW/FcbsotZNPr4k9uz+3QEksMmflWloS9wCnypM7g==", 564 | "dependencies": { 565 | "@vueuse/core": "10.4.1", 566 | "@vueuse/shared": "10.4.1", 567 | "vue-demi": ">=0.14.5" 568 | }, 569 | "funding": { 570 | "url": "https://github.com/sponsors/antfu" 571 | }, 572 | "peerDependencies": { 573 | "async-validator": "*", 574 | "axios": "*", 575 | "change-case": "*", 576 | "drauu": "*", 577 | "focus-trap": "*", 578 | "fuse.js": "*", 579 | "idb-keyval": "*", 580 | "jwt-decode": "*", 581 | "nprogress": "*", 582 | "qrcode": "*", 583 | "sortablejs": "*", 584 | "universal-cookie": "*" 585 | }, 586 | "peerDependenciesMeta": { 587 | "async-validator": { 588 | "optional": true 589 | }, 590 | "axios": { 591 | "optional": true 592 | }, 593 | "change-case": { 594 | "optional": true 595 | }, 596 | "drauu": { 597 | "optional": true 598 | }, 599 | "focus-trap": { 600 | "optional": true 601 | }, 602 | "fuse.js": { 603 | "optional": true 604 | }, 605 | "idb-keyval": { 606 | "optional": true 607 | }, 608 | "jwt-decode": { 609 | "optional": true 610 | }, 611 | "nprogress": { 612 | "optional": true 613 | }, 614 | "qrcode": { 615 | "optional": true 616 | }, 617 | "sortablejs": { 618 | "optional": true 619 | }, 620 | "universal-cookie": { 621 | "optional": true 622 | } 623 | } 624 | }, 625 | "node_modules/@markwhen/timeline/node_modules/@vueuse/metadata": { 626 | "version": "10.4.1", 627 | "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.4.1.tgz", 628 | "integrity": "sha512-2Sc8X+iVzeuMGHr6O2j4gv/zxvQGGOYETYXEc41h0iZXIRnRbJZGmY/QP8dvzqUelf8vg0p/yEA5VpCEu+WpZg==", 629 | "funding": { 630 | "url": "https://github.com/sponsors/antfu" 631 | } 632 | }, 633 | "node_modules/@markwhen/timeline/node_modules/@vueuse/shared": { 634 | "version": "10.4.1", 635 | "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.4.1.tgz", 636 | "integrity": "sha512-vz5hbAM4qA0lDKmcr2y3pPdU+2EVw/yzfRsBdu+6+USGa4PxqSQRYIUC9/NcT06y+ZgaTsyURw2I9qOFaaXHAg==", 637 | "dependencies": { 638 | "vue-demi": ">=0.14.5" 639 | }, 640 | "funding": { 641 | "url": "https://github.com/sponsors/antfu" 642 | } 643 | }, 644 | "node_modules/@markwhen/timeline/node_modules/immer": { 645 | "version": "10.0.2", 646 | "resolved": "https://registry.npmjs.org/immer/-/immer-10.0.2.tgz", 647 | "integrity": "sha512-Rx3CqeqQ19sxUtYV9CU911Vhy8/721wRFnJv3REVGWUmoAcIwzifTsdmJte/MV+0/XpM35LZdQMBGkRIoLPwQA==", 648 | "funding": { 649 | "type": "opencollective", 650 | "url": "https://opencollective.com/immer" 651 | } 652 | }, 653 | "node_modules/@markwhen/view-client": { 654 | "version": "1.4.3", 655 | "resolved": "https://registry.npmjs.org/@markwhen/view-client/-/view-client-1.4.3.tgz", 656 | "integrity": "sha512-nQoieLX27gBUFWhaG5nLeYIFdR3bgKSwFmNufTh5KEVMIvqXG2+QGZfgnon2uUTFMszvZHZK8v9dxG9/N2nUzw==", 657 | "dependencies": { 658 | "@markwhen/parser": "^0.10.7" 659 | } 660 | }, 661 | "node_modules/@nuxt/devalue": { 662 | "version": "2.0.2", 663 | "resolved": "https://registry.npmjs.org/@nuxt/devalue/-/devalue-2.0.2.tgz", 664 | "integrity": "sha512-GBzP8zOc7CGWyFQS6dv1lQz8VVpz5C2yRszbXufwG/9zhStTIH50EtD87NmWbTMwXDvZLNg8GIpb1UFdH93JCA==" 665 | }, 666 | "node_modules/@squadette/hammerjs": { 667 | "version": "2.1.0-pre3", 668 | "resolved": "https://registry.npmjs.org/@squadette/hammerjs/-/hammerjs-2.1.0-pre3.tgz", 669 | "integrity": "sha512-3NXqPTdOwF9tuqpg8UaEqDrncgnq8HEj3dpapoNC3Kkp83BFf5kdzeBdu2aDuNubJFnORSjUKvYuj/3d7RzTIQ==", 670 | "engines": { 671 | "node": ">=0.8.0" 672 | } 673 | }, 674 | "node_modules/@types/body-parser": { 675 | "version": "1.19.2", 676 | "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", 677 | "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", 678 | "dev": true, 679 | "dependencies": { 680 | "@types/connect": "*", 681 | "@types/node": "*" 682 | } 683 | }, 684 | "node_modules/@types/connect": { 685 | "version": "3.4.35", 686 | "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", 687 | "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", 688 | "dev": true, 689 | "dependencies": { 690 | "@types/node": "*" 691 | } 692 | }, 693 | "node_modules/@types/express": { 694 | "version": "4.17.17", 695 | "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", 696 | "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", 697 | "dev": true, 698 | "dependencies": { 699 | "@types/body-parser": "*", 700 | "@types/express-serve-static-core": "^4.17.33", 701 | "@types/qs": "*", 702 | "@types/serve-static": "*" 703 | } 704 | }, 705 | "node_modules/@types/express-serve-static-core": { 706 | "version": "4.17.33", 707 | "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz", 708 | "integrity": "sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==", 709 | "dev": true, 710 | "dependencies": { 711 | "@types/node": "*", 712 | "@types/qs": "*", 713 | "@types/range-parser": "*" 714 | } 715 | }, 716 | "node_modules/@types/luxon": { 717 | "version": "3.3.2", 718 | "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.3.2.tgz", 719 | "integrity": "sha512-l5cpE57br4BIjK+9BSkFBOsWtwv6J9bJpC7gdXIzZyI0vuKvNTk0wZZrkQxMGsUAuGW9+WMNWF2IJMD7br2yeQ==", 720 | "dev": true 721 | }, 722 | "node_modules/@types/mime": { 723 | "version": "3.0.1", 724 | "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", 725 | "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==", 726 | "dev": true 727 | }, 728 | "node_modules/@types/node": { 729 | "version": "18.15.5", 730 | "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.5.tgz", 731 | "integrity": "sha512-Ark2WDjjZO7GmvsyFFf81MXuGTA/d6oP38anyxWOL6EREyBKAxKoFHwBhaZxCfLRLpO8JgVXwqOwSwa7jRcjew==", 732 | "dev": true 733 | }, 734 | "node_modules/@types/qs": { 735 | "version": "6.9.7", 736 | "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", 737 | "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", 738 | "dev": true 739 | }, 740 | "node_modules/@types/range-parser": { 741 | "version": "1.2.4", 742 | "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", 743 | "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", 744 | "dev": true 745 | }, 746 | "node_modules/@types/serve-static": { 747 | "version": "1.15.1", 748 | "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.1.tgz", 749 | "integrity": "sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==", 750 | "dev": true, 751 | "dependencies": { 752 | "@types/mime": "*", 753 | "@types/node": "*" 754 | } 755 | }, 756 | "node_modules/@types/web-bluetooth": { 757 | "version": "0.0.16", 758 | "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz", 759 | "integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==" 760 | }, 761 | "node_modules/@types/ws": { 762 | "version": "8.5.4", 763 | "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.4.tgz", 764 | "integrity": "sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg==", 765 | "dev": true, 766 | "dependencies": { 767 | "@types/node": "*" 768 | } 769 | }, 770 | "node_modules/@types/yargs": { 771 | "version": "17.0.23", 772 | "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.23.tgz", 773 | "integrity": "sha512-yuogunc04OnzGQCrfHx+Kk883Q4X0aSwmYZhKjI21m+SVYzjIbrWl8dOOwSv5hf2Um2pdCOXWo9isteZTNXUZQ==", 774 | "dev": true, 775 | "dependencies": { 776 | "@types/yargs-parser": "*" 777 | } 778 | }, 779 | "node_modules/@types/yargs-parser": { 780 | "version": "21.0.0", 781 | "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", 782 | "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", 783 | "dev": true 784 | }, 785 | "node_modules/@vue/compiler-core": { 786 | "version": "3.3.4", 787 | "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.3.4.tgz", 788 | "integrity": "sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==", 789 | "dependencies": { 790 | "@babel/parser": "^7.21.3", 791 | "@vue/shared": "3.3.4", 792 | "estree-walker": "^2.0.2", 793 | "source-map-js": "^1.0.2" 794 | } 795 | }, 796 | "node_modules/@vue/compiler-dom": { 797 | "version": "3.3.4", 798 | "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.3.4.tgz", 799 | "integrity": "sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==", 800 | "dependencies": { 801 | "@vue/compiler-core": "3.3.4", 802 | "@vue/shared": "3.3.4" 803 | } 804 | }, 805 | "node_modules/@vue/compiler-sfc": { 806 | "version": "3.3.4", 807 | "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.3.4.tgz", 808 | "integrity": "sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==", 809 | "dependencies": { 810 | "@babel/parser": "^7.20.15", 811 | "@vue/compiler-core": "3.3.4", 812 | "@vue/compiler-dom": "3.3.4", 813 | "@vue/compiler-ssr": "3.3.4", 814 | "@vue/reactivity-transform": "3.3.4", 815 | "@vue/shared": "3.3.4", 816 | "estree-walker": "^2.0.2", 817 | "magic-string": "^0.30.0", 818 | "postcss": "^8.1.10", 819 | "source-map-js": "^1.0.2" 820 | } 821 | }, 822 | "node_modules/@vue/compiler-ssr": { 823 | "version": "3.3.4", 824 | "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.3.4.tgz", 825 | "integrity": "sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==", 826 | "dependencies": { 827 | "@vue/compiler-dom": "3.3.4", 828 | "@vue/shared": "3.3.4" 829 | } 830 | }, 831 | "node_modules/@vue/devtools-api": { 832 | "version": "6.5.0", 833 | "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.0.tgz", 834 | "integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==" 835 | }, 836 | "node_modules/@vue/reactivity": { 837 | "version": "3.3.4", 838 | "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.3.4.tgz", 839 | "integrity": "sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==", 840 | "dependencies": { 841 | "@vue/shared": "3.3.4" 842 | } 843 | }, 844 | "node_modules/@vue/reactivity-transform": { 845 | "version": "3.3.4", 846 | "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.3.4.tgz", 847 | "integrity": "sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==", 848 | "dependencies": { 849 | "@babel/parser": "^7.20.15", 850 | "@vue/compiler-core": "3.3.4", 851 | "@vue/shared": "3.3.4", 852 | "estree-walker": "^2.0.2", 853 | "magic-string": "^0.30.0" 854 | } 855 | }, 856 | "node_modules/@vue/runtime-core": { 857 | "version": "3.3.4", 858 | "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.3.4.tgz", 859 | "integrity": "sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA==", 860 | "dependencies": { 861 | "@vue/reactivity": "3.3.4", 862 | "@vue/shared": "3.3.4" 863 | } 864 | }, 865 | "node_modules/@vue/runtime-dom": { 866 | "version": "3.3.4", 867 | "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.3.4.tgz", 868 | "integrity": "sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ==", 869 | "dependencies": { 870 | "@vue/runtime-core": "3.3.4", 871 | "@vue/shared": "3.3.4", 872 | "csstype": "^3.1.1" 873 | } 874 | }, 875 | "node_modules/@vue/server-renderer": { 876 | "version": "3.3.4", 877 | "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.3.4.tgz", 878 | "integrity": "sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ==", 879 | "dependencies": { 880 | "@vue/compiler-ssr": "3.3.4", 881 | "@vue/shared": "3.3.4" 882 | }, 883 | "peerDependencies": { 884 | "vue": "3.3.4" 885 | } 886 | }, 887 | "node_modules/@vue/shared": { 888 | "version": "3.3.4", 889 | "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.4.tgz", 890 | "integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==" 891 | }, 892 | "node_modules/@vueuse/core": { 893 | "version": "9.13.0", 894 | "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-9.13.0.tgz", 895 | "integrity": "sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==", 896 | "dependencies": { 897 | "@types/web-bluetooth": "^0.0.16", 898 | "@vueuse/metadata": "9.13.0", 899 | "@vueuse/shared": "9.13.0", 900 | "vue-demi": "*" 901 | }, 902 | "funding": { 903 | "url": "https://github.com/sponsors/antfu" 904 | } 905 | }, 906 | "node_modules/@vueuse/integrations": { 907 | "version": "9.13.0", 908 | "resolved": "https://registry.npmjs.org/@vueuse/integrations/-/integrations-9.13.0.tgz", 909 | "integrity": "sha512-I1kX/tsfcvWWLZD7HZaP0LsSfchK13YxReLfharXhk72SFXp87doLbRaTfIF5w8m/gr/vPtcNyQPAXW7Ubpuww==", 910 | "dependencies": { 911 | "@vueuse/core": "9.13.0", 912 | "@vueuse/shared": "9.13.0", 913 | "vue-demi": "*" 914 | }, 915 | "funding": { 916 | "url": "https://github.com/sponsors/antfu" 917 | }, 918 | "peerDependencies": { 919 | "async-validator": "*", 920 | "axios": "*", 921 | "change-case": "*", 922 | "drauu": "*", 923 | "focus-trap": "*", 924 | "fuse.js": "*", 925 | "idb-keyval": "*", 926 | "jwt-decode": "*", 927 | "nprogress": "*", 928 | "qrcode": "*", 929 | "universal-cookie": "*" 930 | }, 931 | "peerDependenciesMeta": { 932 | "async-validator": { 933 | "optional": true 934 | }, 935 | "axios": { 936 | "optional": true 937 | }, 938 | "change-case": { 939 | "optional": true 940 | }, 941 | "drauu": { 942 | "optional": true 943 | }, 944 | "focus-trap": { 945 | "optional": true 946 | }, 947 | "fuse.js": { 948 | "optional": true 949 | }, 950 | "idb-keyval": { 951 | "optional": true 952 | }, 953 | "jwt-decode": { 954 | "optional": true 955 | }, 956 | "nprogress": { 957 | "optional": true 958 | }, 959 | "qrcode": { 960 | "optional": true 961 | }, 962 | "universal-cookie": { 963 | "optional": true 964 | } 965 | } 966 | }, 967 | "node_modules/@vueuse/metadata": { 968 | "version": "9.13.0", 969 | "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.13.0.tgz", 970 | "integrity": "sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==", 971 | "funding": { 972 | "url": "https://github.com/sponsors/antfu" 973 | } 974 | }, 975 | "node_modules/@vueuse/shared": { 976 | "version": "9.13.0", 977 | "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-9.13.0.tgz", 978 | "integrity": "sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==", 979 | "dependencies": { 980 | "vue-demi": "*" 981 | }, 982 | "funding": { 983 | "url": "https://github.com/sponsors/antfu" 984 | } 985 | }, 986 | "node_modules/accepts": { 987 | "version": "1.3.8", 988 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", 989 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 990 | "dependencies": { 991 | "mime-types": "~2.1.34", 992 | "negotiator": "0.6.3" 993 | }, 994 | "engines": { 995 | "node": ">= 0.6" 996 | } 997 | }, 998 | "node_modules/ansi-regex": { 999 | "version": "5.0.1", 1000 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 1001 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 1002 | "engines": { 1003 | "node": ">=8" 1004 | } 1005 | }, 1006 | "node_modules/ansi-styles": { 1007 | "version": "4.3.0", 1008 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 1009 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 1010 | "dependencies": { 1011 | "color-convert": "^2.0.1" 1012 | }, 1013 | "engines": { 1014 | "node": ">=8" 1015 | }, 1016 | "funding": { 1017 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 1018 | } 1019 | }, 1020 | "node_modules/array-flatten": { 1021 | "version": "1.1.1", 1022 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 1023 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" 1024 | }, 1025 | "node_modules/body-parser": { 1026 | "version": "1.20.1", 1027 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", 1028 | "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", 1029 | "dependencies": { 1030 | "bytes": "3.1.2", 1031 | "content-type": "~1.0.4", 1032 | "debug": "2.6.9", 1033 | "depd": "2.0.0", 1034 | "destroy": "1.2.0", 1035 | "http-errors": "2.0.0", 1036 | "iconv-lite": "0.4.24", 1037 | "on-finished": "2.4.1", 1038 | "qs": "6.11.0", 1039 | "raw-body": "2.5.1", 1040 | "type-is": "~1.6.18", 1041 | "unpipe": "1.0.0" 1042 | }, 1043 | "engines": { 1044 | "node": ">= 0.8", 1045 | "npm": "1.2.8000 || >= 1.4.16" 1046 | } 1047 | }, 1048 | "node_modules/boolbase": { 1049 | "version": "1.0.0", 1050 | "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", 1051 | "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" 1052 | }, 1053 | "node_modules/bytes": { 1054 | "version": "3.1.2", 1055 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 1056 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 1057 | "engines": { 1058 | "node": ">= 0.8" 1059 | } 1060 | }, 1061 | "node_modules/call-bind": { 1062 | "version": "1.0.2", 1063 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", 1064 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", 1065 | "dependencies": { 1066 | "function-bind": "^1.1.1", 1067 | "get-intrinsic": "^1.0.2" 1068 | }, 1069 | "funding": { 1070 | "url": "https://github.com/sponsors/ljharb" 1071 | } 1072 | }, 1073 | "node_modules/cliui": { 1074 | "version": "8.0.1", 1075 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", 1076 | "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", 1077 | "dependencies": { 1078 | "string-width": "^4.2.0", 1079 | "strip-ansi": "^6.0.1", 1080 | "wrap-ansi": "^7.0.0" 1081 | }, 1082 | "engines": { 1083 | "node": ">=12" 1084 | } 1085 | }, 1086 | "node_modules/color-convert": { 1087 | "version": "2.0.1", 1088 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 1089 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 1090 | "dependencies": { 1091 | "color-name": "~1.1.4" 1092 | }, 1093 | "engines": { 1094 | "node": ">=7.0.0" 1095 | } 1096 | }, 1097 | "node_modules/color-name": { 1098 | "version": "1.1.4", 1099 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 1100 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" 1101 | }, 1102 | "node_modules/content-disposition": { 1103 | "version": "0.5.4", 1104 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", 1105 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 1106 | "dependencies": { 1107 | "safe-buffer": "5.2.1" 1108 | }, 1109 | "engines": { 1110 | "node": ">= 0.6" 1111 | } 1112 | }, 1113 | "node_modules/content-type": { 1114 | "version": "1.0.5", 1115 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", 1116 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", 1117 | "engines": { 1118 | "node": ">= 0.6" 1119 | } 1120 | }, 1121 | "node_modules/cookie": { 1122 | "version": "0.5.0", 1123 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", 1124 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", 1125 | "engines": { 1126 | "node": ">= 0.6" 1127 | } 1128 | }, 1129 | "node_modules/cookie-signature": { 1130 | "version": "1.0.6", 1131 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 1132 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" 1133 | }, 1134 | "node_modules/cross-spawn": { 1135 | "version": "7.0.3", 1136 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", 1137 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", 1138 | "dev": true, 1139 | "dependencies": { 1140 | "path-key": "^3.1.0", 1141 | "shebang-command": "^2.0.0", 1142 | "which": "^2.0.1" 1143 | }, 1144 | "engines": { 1145 | "node": ">= 8" 1146 | } 1147 | }, 1148 | "node_modules/css-select": { 1149 | "version": "5.1.0", 1150 | "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", 1151 | "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", 1152 | "dependencies": { 1153 | "boolbase": "^1.0.0", 1154 | "css-what": "^6.1.0", 1155 | "domhandler": "^5.0.2", 1156 | "domutils": "^3.0.1", 1157 | "nth-check": "^2.0.1" 1158 | }, 1159 | "funding": { 1160 | "url": "https://github.com/sponsors/fb55" 1161 | } 1162 | }, 1163 | "node_modules/css-what": { 1164 | "version": "6.1.0", 1165 | "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", 1166 | "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", 1167 | "engines": { 1168 | "node": ">= 6" 1169 | }, 1170 | "funding": { 1171 | "url": "https://github.com/sponsors/fb55" 1172 | } 1173 | }, 1174 | "node_modules/csstype": { 1175 | "version": "3.1.2", 1176 | "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", 1177 | "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" 1178 | }, 1179 | "node_modules/debug": { 1180 | "version": "2.6.9", 1181 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 1182 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 1183 | "dependencies": { 1184 | "ms": "2.0.0" 1185 | } 1186 | }, 1187 | "node_modules/depd": { 1188 | "version": "2.0.0", 1189 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 1190 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 1191 | "engines": { 1192 | "node": ">= 0.8" 1193 | } 1194 | }, 1195 | "node_modules/destroy": { 1196 | "version": "1.2.0", 1197 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", 1198 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", 1199 | "engines": { 1200 | "node": ">= 0.8", 1201 | "npm": "1.2.8000 || >= 1.4.16" 1202 | } 1203 | }, 1204 | "node_modules/dom-serializer": { 1205 | "version": "2.0.0", 1206 | "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", 1207 | "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", 1208 | "dependencies": { 1209 | "domelementtype": "^2.3.0", 1210 | "domhandler": "^5.0.2", 1211 | "entities": "^4.2.0" 1212 | }, 1213 | "funding": { 1214 | "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" 1215 | } 1216 | }, 1217 | "node_modules/domelementtype": { 1218 | "version": "2.3.0", 1219 | "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", 1220 | "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", 1221 | "funding": [ 1222 | { 1223 | "type": "github", 1224 | "url": "https://github.com/sponsors/fb55" 1225 | } 1226 | ] 1227 | }, 1228 | "node_modules/domhandler": { 1229 | "version": "5.0.3", 1230 | "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", 1231 | "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", 1232 | "dependencies": { 1233 | "domelementtype": "^2.3.0" 1234 | }, 1235 | "engines": { 1236 | "node": ">= 4" 1237 | }, 1238 | "funding": { 1239 | "url": "https://github.com/fb55/domhandler?sponsor=1" 1240 | } 1241 | }, 1242 | "node_modules/domutils": { 1243 | "version": "3.0.1", 1244 | "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", 1245 | "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", 1246 | "dependencies": { 1247 | "dom-serializer": "^2.0.0", 1248 | "domelementtype": "^2.3.0", 1249 | "domhandler": "^5.0.1" 1250 | }, 1251 | "funding": { 1252 | "url": "https://github.com/fb55/domutils?sponsor=1" 1253 | } 1254 | }, 1255 | "node_modules/duplexer": { 1256 | "version": "0.1.2", 1257 | "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", 1258 | "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", 1259 | "dev": true 1260 | }, 1261 | "node_modules/ee-first": { 1262 | "version": "1.1.1", 1263 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 1264 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" 1265 | }, 1266 | "node_modules/emoji-regex": { 1267 | "version": "8.0.0", 1268 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 1269 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" 1270 | }, 1271 | "node_modules/encodeurl": { 1272 | "version": "1.0.2", 1273 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 1274 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", 1275 | "engines": { 1276 | "node": ">= 0.8" 1277 | } 1278 | }, 1279 | "node_modules/entities": { 1280 | "version": "4.4.0", 1281 | "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", 1282 | "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==", 1283 | "engines": { 1284 | "node": ">=0.12" 1285 | }, 1286 | "funding": { 1287 | "url": "https://github.com/fb55/entities?sponsor=1" 1288 | } 1289 | }, 1290 | "node_modules/esbuild": { 1291 | "version": "0.17.12", 1292 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.12.tgz", 1293 | "integrity": "sha512-bX/zHl7Gn2CpQwcMtRogTTBf9l1nl+H6R8nUbjk+RuKqAE3+8FDulLA+pHvX7aA7Xe07Iwa+CWvy9I8Y2qqPKQ==", 1294 | "dev": true, 1295 | "hasInstallScript": true, 1296 | "bin": { 1297 | "esbuild": "bin/esbuild" 1298 | }, 1299 | "engines": { 1300 | "node": ">=12" 1301 | }, 1302 | "optionalDependencies": { 1303 | "@esbuild/android-arm": "0.17.12", 1304 | "@esbuild/android-arm64": "0.17.12", 1305 | "@esbuild/android-x64": "0.17.12", 1306 | "@esbuild/darwin-arm64": "0.17.12", 1307 | "@esbuild/darwin-x64": "0.17.12", 1308 | "@esbuild/freebsd-arm64": "0.17.12", 1309 | "@esbuild/freebsd-x64": "0.17.12", 1310 | "@esbuild/linux-arm": "0.17.12", 1311 | "@esbuild/linux-arm64": "0.17.12", 1312 | "@esbuild/linux-ia32": "0.17.12", 1313 | "@esbuild/linux-loong64": "0.17.12", 1314 | "@esbuild/linux-mips64el": "0.17.12", 1315 | "@esbuild/linux-ppc64": "0.17.12", 1316 | "@esbuild/linux-riscv64": "0.17.12", 1317 | "@esbuild/linux-s390x": "0.17.12", 1318 | "@esbuild/linux-x64": "0.17.12", 1319 | "@esbuild/netbsd-x64": "0.17.12", 1320 | "@esbuild/openbsd-x64": "0.17.12", 1321 | "@esbuild/sunos-x64": "0.17.12", 1322 | "@esbuild/win32-arm64": "0.17.12", 1323 | "@esbuild/win32-ia32": "0.17.12", 1324 | "@esbuild/win32-x64": "0.17.12" 1325 | } 1326 | }, 1327 | "node_modules/escalade": { 1328 | "version": "3.1.1", 1329 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", 1330 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", 1331 | "engines": { 1332 | "node": ">=6" 1333 | } 1334 | }, 1335 | "node_modules/escape-html": { 1336 | "version": "1.0.3", 1337 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 1338 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" 1339 | }, 1340 | "node_modules/estree-walker": { 1341 | "version": "2.0.2", 1342 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", 1343 | "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" 1344 | }, 1345 | "node_modules/etag": { 1346 | "version": "1.8.1", 1347 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 1348 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", 1349 | "engines": { 1350 | "node": ">= 0.6" 1351 | } 1352 | }, 1353 | "node_modules/event-stream": { 1354 | "version": "3.3.4", 1355 | "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", 1356 | "integrity": "sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==", 1357 | "dev": true, 1358 | "dependencies": { 1359 | "duplexer": "~0.1.1", 1360 | "from": "~0", 1361 | "map-stream": "~0.1.0", 1362 | "pause-stream": "0.0.11", 1363 | "split": "0.3", 1364 | "stream-combiner": "~0.0.4", 1365 | "through": "~2.3.1" 1366 | } 1367 | }, 1368 | "node_modules/express": { 1369 | "version": "4.18.2", 1370 | "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", 1371 | "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", 1372 | "dependencies": { 1373 | "accepts": "~1.3.8", 1374 | "array-flatten": "1.1.1", 1375 | "body-parser": "1.20.1", 1376 | "content-disposition": "0.5.4", 1377 | "content-type": "~1.0.4", 1378 | "cookie": "0.5.0", 1379 | "cookie-signature": "1.0.6", 1380 | "debug": "2.6.9", 1381 | "depd": "2.0.0", 1382 | "encodeurl": "~1.0.2", 1383 | "escape-html": "~1.0.3", 1384 | "etag": "~1.8.1", 1385 | "finalhandler": "1.2.0", 1386 | "fresh": "0.5.2", 1387 | "http-errors": "2.0.0", 1388 | "merge-descriptors": "1.0.1", 1389 | "methods": "~1.1.2", 1390 | "on-finished": "2.4.1", 1391 | "parseurl": "~1.3.3", 1392 | "path-to-regexp": "0.1.7", 1393 | "proxy-addr": "~2.0.7", 1394 | "qs": "6.11.0", 1395 | "range-parser": "~1.2.1", 1396 | "safe-buffer": "5.2.1", 1397 | "send": "0.18.0", 1398 | "serve-static": "1.15.0", 1399 | "setprototypeof": "1.2.0", 1400 | "statuses": "2.0.1", 1401 | "type-is": "~1.6.18", 1402 | "utils-merge": "1.0.1", 1403 | "vary": "~1.1.2" 1404 | }, 1405 | "engines": { 1406 | "node": ">= 0.10.0" 1407 | } 1408 | }, 1409 | "node_modules/finalhandler": { 1410 | "version": "1.2.0", 1411 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", 1412 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", 1413 | "dependencies": { 1414 | "debug": "2.6.9", 1415 | "encodeurl": "~1.0.2", 1416 | "escape-html": "~1.0.3", 1417 | "on-finished": "2.4.1", 1418 | "parseurl": "~1.3.3", 1419 | "statuses": "2.0.1", 1420 | "unpipe": "~1.0.0" 1421 | }, 1422 | "engines": { 1423 | "node": ">= 0.8" 1424 | } 1425 | }, 1426 | "node_modules/forwarded": { 1427 | "version": "0.2.0", 1428 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 1429 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", 1430 | "engines": { 1431 | "node": ">= 0.6" 1432 | } 1433 | }, 1434 | "node_modules/fresh": { 1435 | "version": "0.5.2", 1436 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 1437 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", 1438 | "engines": { 1439 | "node": ">= 0.6" 1440 | } 1441 | }, 1442 | "node_modules/from": { 1443 | "version": "0.1.7", 1444 | "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", 1445 | "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==", 1446 | "dev": true 1447 | }, 1448 | "node_modules/function-bind": { 1449 | "version": "1.1.1", 1450 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 1451 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" 1452 | }, 1453 | "node_modules/get-caller-file": { 1454 | "version": "2.0.5", 1455 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 1456 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 1457 | "engines": { 1458 | "node": "6.* || 8.* || >= 10.*" 1459 | } 1460 | }, 1461 | "node_modules/get-intrinsic": { 1462 | "version": "1.2.0", 1463 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", 1464 | "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", 1465 | "dependencies": { 1466 | "function-bind": "^1.1.1", 1467 | "has": "^1.0.3", 1468 | "has-symbols": "^1.0.3" 1469 | }, 1470 | "funding": { 1471 | "url": "https://github.com/sponsors/ljharb" 1472 | } 1473 | }, 1474 | "node_modules/has": { 1475 | "version": "1.0.3", 1476 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 1477 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 1478 | "dependencies": { 1479 | "function-bind": "^1.1.1" 1480 | }, 1481 | "engines": { 1482 | "node": ">= 0.4.0" 1483 | } 1484 | }, 1485 | "node_modules/has-symbols": { 1486 | "version": "1.0.3", 1487 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 1488 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", 1489 | "engines": { 1490 | "node": ">= 0.4" 1491 | }, 1492 | "funding": { 1493 | "url": "https://github.com/sponsors/ljharb" 1494 | } 1495 | }, 1496 | "node_modules/he": { 1497 | "version": "1.2.0", 1498 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", 1499 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", 1500 | "bin": { 1501 | "he": "bin/he" 1502 | } 1503 | }, 1504 | "node_modules/http-errors": { 1505 | "version": "2.0.0", 1506 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 1507 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 1508 | "dependencies": { 1509 | "depd": "2.0.0", 1510 | "inherits": "2.0.4", 1511 | "setprototypeof": "1.2.0", 1512 | "statuses": "2.0.1", 1513 | "toidentifier": "1.0.1" 1514 | }, 1515 | "engines": { 1516 | "node": ">= 0.8" 1517 | } 1518 | }, 1519 | "node_modules/ical.js": { 1520 | "version": "1.5.0", 1521 | "resolved": "https://registry.npmjs.org/ical.js/-/ical.js-1.5.0.tgz", 1522 | "integrity": "sha512-7ZxMkogUkkaCx810yp0ZGKvq1ZpRgJeornPttpoxe6nYZ3NLesZe1wWMXDdwTkj/b5NtXT+Y16Aakph/ao98ZQ==" 1523 | }, 1524 | "node_modules/iconv-lite": { 1525 | "version": "0.4.24", 1526 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 1527 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 1528 | "dependencies": { 1529 | "safer-buffer": ">= 2.1.2 < 3" 1530 | }, 1531 | "engines": { 1532 | "node": ">=0.10.0" 1533 | } 1534 | }, 1535 | "node_modules/immer": { 1536 | "version": "9.0.19", 1537 | "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.19.tgz", 1538 | "integrity": "sha512-eY+Y0qcsB4TZKwgQzLaE/lqYMlKhv5J9dyd2RhhtGhNo2njPXDqU9XPfcNfa3MIDsdtZt5KlkIsirlo4dHsWdQ==", 1539 | "funding": { 1540 | "type": "opencollective", 1541 | "url": "https://opencollective.com/immer" 1542 | } 1543 | }, 1544 | "node_modules/inherits": { 1545 | "version": "2.0.4", 1546 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 1547 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 1548 | }, 1549 | "node_modules/ipaddr.js": { 1550 | "version": "1.9.1", 1551 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 1552 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", 1553 | "engines": { 1554 | "node": ">= 0.10" 1555 | } 1556 | }, 1557 | "node_modules/is-fullwidth-code-point": { 1558 | "version": "3.0.0", 1559 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 1560 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 1561 | "engines": { 1562 | "node": ">=8" 1563 | } 1564 | }, 1565 | "node_modules/isexe": { 1566 | "version": "2.0.0", 1567 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 1568 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 1569 | "dev": true 1570 | }, 1571 | "node_modules/js-tokens": { 1572 | "version": "4.0.0", 1573 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 1574 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" 1575 | }, 1576 | "node_modules/loose-envify": { 1577 | "version": "1.4.0", 1578 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", 1579 | "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", 1580 | "dependencies": { 1581 | "js-tokens": "^3.0.0 || ^4.0.0" 1582 | }, 1583 | "bin": { 1584 | "loose-envify": "cli.js" 1585 | } 1586 | }, 1587 | "node_modules/lru-cache": { 1588 | "version": "7.18.3", 1589 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", 1590 | "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", 1591 | "engines": { 1592 | "node": ">=12" 1593 | } 1594 | }, 1595 | "node_modules/luxon": { 1596 | "version": "3.4.3", 1597 | "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.3.tgz", 1598 | "integrity": "sha512-tFWBiv3h7z+T/tDaoxA8rqTxy1CHV6gHS//QdaH4pulbq/JuBSGgQspQQqcgnwdAx6pNI7cmvz5Sv/addzHmUg==", 1599 | "engines": { 1600 | "node": ">=12" 1601 | } 1602 | }, 1603 | "node_modules/magic-string": { 1604 | "version": "0.30.3", 1605 | "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.3.tgz", 1606 | "integrity": "sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==", 1607 | "dependencies": { 1608 | "@jridgewell/sourcemap-codec": "^1.4.15" 1609 | }, 1610 | "engines": { 1611 | "node": ">=12" 1612 | } 1613 | }, 1614 | "node_modules/map-stream": { 1615 | "version": "0.1.0", 1616 | "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", 1617 | "integrity": "sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==", 1618 | "dev": true 1619 | }, 1620 | "node_modules/media-typer": { 1621 | "version": "0.3.0", 1622 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 1623 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", 1624 | "engines": { 1625 | "node": ">= 0.6" 1626 | } 1627 | }, 1628 | "node_modules/merge-descriptors": { 1629 | "version": "1.0.1", 1630 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 1631 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" 1632 | }, 1633 | "node_modules/methods": { 1634 | "version": "1.1.2", 1635 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 1636 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", 1637 | "engines": { 1638 | "node": ">= 0.6" 1639 | } 1640 | }, 1641 | "node_modules/mime": { 1642 | "version": "1.6.0", 1643 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 1644 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", 1645 | "bin": { 1646 | "mime": "cli.js" 1647 | }, 1648 | "engines": { 1649 | "node": ">=4" 1650 | } 1651 | }, 1652 | "node_modules/mime-db": { 1653 | "version": "1.52.0", 1654 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 1655 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 1656 | "engines": { 1657 | "node": ">= 0.6" 1658 | } 1659 | }, 1660 | "node_modules/mime-types": { 1661 | "version": "2.1.35", 1662 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 1663 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 1664 | "dependencies": { 1665 | "mime-db": "1.52.0" 1666 | }, 1667 | "engines": { 1668 | "node": ">= 0.6" 1669 | } 1670 | }, 1671 | "node_modules/ms": { 1672 | "version": "2.0.0", 1673 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1674 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" 1675 | }, 1676 | "node_modules/nanoid": { 1677 | "version": "3.3.6", 1678 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", 1679 | "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", 1680 | "funding": [ 1681 | { 1682 | "type": "github", 1683 | "url": "https://github.com/sponsors/ai" 1684 | } 1685 | ], 1686 | "bin": { 1687 | "nanoid": "bin/nanoid.cjs" 1688 | }, 1689 | "engines": { 1690 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 1691 | } 1692 | }, 1693 | "node_modules/negotiator": { 1694 | "version": "0.6.3", 1695 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", 1696 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", 1697 | "engines": { 1698 | "node": ">= 0.6" 1699 | } 1700 | }, 1701 | "node_modules/node-cleanup": { 1702 | "version": "2.1.2", 1703 | "resolved": "https://registry.npmjs.org/node-cleanup/-/node-cleanup-2.1.2.tgz", 1704 | "integrity": "sha512-qN8v/s2PAJwGUtr1/hYTpNKlD6Y9rc4p8KSmJXyGdYGZsDGKXrGThikLFP9OCHFeLeEpQzPwiAtdIvBLqm//Hw==", 1705 | "dev": true 1706 | }, 1707 | "node_modules/node-html-parser": { 1708 | "version": "6.1.10", 1709 | "resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-6.1.10.tgz", 1710 | "integrity": "sha512-6/uWdWxjQWQ7tMcFK2wWlrflsQUzh1HsEzlIf2j5+TtzfhT2yUvg3DwZYAmjEHeR3uX74ko7exjHW69J0tOzIg==", 1711 | "dependencies": { 1712 | "css-select": "^5.1.0", 1713 | "he": "1.2.0" 1714 | } 1715 | }, 1716 | "node_modules/nth-check": { 1717 | "version": "2.1.1", 1718 | "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", 1719 | "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", 1720 | "dependencies": { 1721 | "boolbase": "^1.0.0" 1722 | }, 1723 | "funding": { 1724 | "url": "https://github.com/fb55/nth-check?sponsor=1" 1725 | } 1726 | }, 1727 | "node_modules/object-inspect": { 1728 | "version": "1.12.3", 1729 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", 1730 | "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", 1731 | "funding": { 1732 | "url": "https://github.com/sponsors/ljharb" 1733 | } 1734 | }, 1735 | "node_modules/on-finished": { 1736 | "version": "2.4.1", 1737 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", 1738 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 1739 | "dependencies": { 1740 | "ee-first": "1.1.1" 1741 | }, 1742 | "engines": { 1743 | "node": ">= 0.8" 1744 | } 1745 | }, 1746 | "node_modules/parseurl": { 1747 | "version": "1.3.3", 1748 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 1749 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", 1750 | "engines": { 1751 | "node": ">= 0.8" 1752 | } 1753 | }, 1754 | "node_modules/path-key": { 1755 | "version": "3.1.1", 1756 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 1757 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 1758 | "dev": true, 1759 | "engines": { 1760 | "node": ">=8" 1761 | } 1762 | }, 1763 | "node_modules/path-to-regexp": { 1764 | "version": "0.1.7", 1765 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 1766 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" 1767 | }, 1768 | "node_modules/pause-stream": { 1769 | "version": "0.0.11", 1770 | "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", 1771 | "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==", 1772 | "dev": true, 1773 | "dependencies": { 1774 | "through": "~2.3" 1775 | } 1776 | }, 1777 | "node_modules/picocolors": { 1778 | "version": "1.0.0", 1779 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", 1780 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" 1781 | }, 1782 | "node_modules/pinia": { 1783 | "version": "2.1.6", 1784 | "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.1.6.tgz", 1785 | "integrity": "sha512-bIU6QuE5qZviMmct5XwCesXelb5VavdOWKWaB17ggk++NUwQWWbP5YnsONTk3b752QkW9sACiR81rorpeOMSvQ==", 1786 | "dependencies": { 1787 | "@vue/devtools-api": "^6.5.0", 1788 | "vue-demi": ">=0.14.5" 1789 | }, 1790 | "funding": { 1791 | "url": "https://github.com/sponsors/posva" 1792 | }, 1793 | "peerDependencies": { 1794 | "@vue/composition-api": "^1.4.0", 1795 | "typescript": ">=4.4.4", 1796 | "vue": "^2.6.14 || ^3.3.0" 1797 | }, 1798 | "peerDependenciesMeta": { 1799 | "@vue/composition-api": { 1800 | "optional": true 1801 | }, 1802 | "typescript": { 1803 | "optional": true 1804 | } 1805 | } 1806 | }, 1807 | "node_modules/postcss": { 1808 | "version": "8.4.30", 1809 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.30.tgz", 1810 | "integrity": "sha512-7ZEao1g4kd68l97aWG/etQKPKq07us0ieSZ2TnFDk11i0ZfDW2AwKHYU8qv4MZKqN2fdBfg+7q0ES06UA73C1g==", 1811 | "funding": [ 1812 | { 1813 | "type": "opencollective", 1814 | "url": "https://opencollective.com/postcss/" 1815 | }, 1816 | { 1817 | "type": "tidelift", 1818 | "url": "https://tidelift.com/funding/github/npm/postcss" 1819 | }, 1820 | { 1821 | "type": "github", 1822 | "url": "https://github.com/sponsors/ai" 1823 | } 1824 | ], 1825 | "dependencies": { 1826 | "nanoid": "^3.3.6", 1827 | "picocolors": "^1.0.0", 1828 | "source-map-js": "^1.0.2" 1829 | }, 1830 | "engines": { 1831 | "node": "^10 || ^12 || >=14" 1832 | } 1833 | }, 1834 | "node_modules/preact": { 1835 | "version": "10.12.1", 1836 | "resolved": "https://registry.npmjs.org/preact/-/preact-10.12.1.tgz", 1837 | "integrity": "sha512-l8386ixSsBdbreOAkqtrwqHwdvR35ID8c3rKPa8lCWuO86dBi32QWHV4vfsZK1utLLFMvw+Z5Ad4XLkZzchscg==", 1838 | "funding": { 1839 | "type": "opencollective", 1840 | "url": "https://opencollective.com/preact" 1841 | } 1842 | }, 1843 | "node_modules/proxy-addr": { 1844 | "version": "2.0.7", 1845 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 1846 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 1847 | "dependencies": { 1848 | "forwarded": "0.2.0", 1849 | "ipaddr.js": "1.9.1" 1850 | }, 1851 | "engines": { 1852 | "node": ">= 0.10" 1853 | } 1854 | }, 1855 | "node_modules/ps-tree": { 1856 | "version": "1.2.0", 1857 | "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz", 1858 | "integrity": "sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==", 1859 | "dev": true, 1860 | "dependencies": { 1861 | "event-stream": "=3.3.4" 1862 | }, 1863 | "bin": { 1864 | "ps-tree": "bin/ps-tree.js" 1865 | }, 1866 | "engines": { 1867 | "node": ">= 0.10" 1868 | } 1869 | }, 1870 | "node_modules/qs": { 1871 | "version": "6.11.0", 1872 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", 1873 | "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", 1874 | "dependencies": { 1875 | "side-channel": "^1.0.4" 1876 | }, 1877 | "engines": { 1878 | "node": ">=0.6" 1879 | }, 1880 | "funding": { 1881 | "url": "https://github.com/sponsors/ljharb" 1882 | } 1883 | }, 1884 | "node_modules/range-parser": { 1885 | "version": "1.2.1", 1886 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 1887 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", 1888 | "engines": { 1889 | "node": ">= 0.6" 1890 | } 1891 | }, 1892 | "node_modules/raw-body": { 1893 | "version": "2.5.1", 1894 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", 1895 | "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", 1896 | "dependencies": { 1897 | "bytes": "3.1.2", 1898 | "http-errors": "2.0.0", 1899 | "iconv-lite": "0.4.24", 1900 | "unpipe": "1.0.0" 1901 | }, 1902 | "engines": { 1903 | "node": ">= 0.8" 1904 | } 1905 | }, 1906 | "node_modules/react": { 1907 | "version": "18.2.0", 1908 | "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", 1909 | "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", 1910 | "dependencies": { 1911 | "loose-envify": "^1.1.0" 1912 | }, 1913 | "engines": { 1914 | "node": ">=0.10.0" 1915 | } 1916 | }, 1917 | "node_modules/react-dom": { 1918 | "version": "18.2.0", 1919 | "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", 1920 | "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", 1921 | "dependencies": { 1922 | "loose-envify": "^1.1.0", 1923 | "scheduler": "^0.23.0" 1924 | }, 1925 | "peerDependencies": { 1926 | "react": "^18.2.0" 1927 | } 1928 | }, 1929 | "node_modules/require-directory": { 1930 | "version": "2.1.1", 1931 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 1932 | "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", 1933 | "engines": { 1934 | "node": ">=0.10.0" 1935 | } 1936 | }, 1937 | "node_modules/safe-buffer": { 1938 | "version": "5.2.1", 1939 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1940 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 1941 | "funding": [ 1942 | { 1943 | "type": "github", 1944 | "url": "https://github.com/sponsors/feross" 1945 | }, 1946 | { 1947 | "type": "patreon", 1948 | "url": "https://www.patreon.com/feross" 1949 | }, 1950 | { 1951 | "type": "consulting", 1952 | "url": "https://feross.org/support" 1953 | } 1954 | ] 1955 | }, 1956 | "node_modules/safer-buffer": { 1957 | "version": "2.1.2", 1958 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1959 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 1960 | }, 1961 | "node_modules/scheduler": { 1962 | "version": "0.23.0", 1963 | "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", 1964 | "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", 1965 | "dependencies": { 1966 | "loose-envify": "^1.1.0" 1967 | } 1968 | }, 1969 | "node_modules/send": { 1970 | "version": "0.18.0", 1971 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", 1972 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", 1973 | "dependencies": { 1974 | "debug": "2.6.9", 1975 | "depd": "2.0.0", 1976 | "destroy": "1.2.0", 1977 | "encodeurl": "~1.0.2", 1978 | "escape-html": "~1.0.3", 1979 | "etag": "~1.8.1", 1980 | "fresh": "0.5.2", 1981 | "http-errors": "2.0.0", 1982 | "mime": "1.6.0", 1983 | "ms": "2.1.3", 1984 | "on-finished": "2.4.1", 1985 | "range-parser": "~1.2.1", 1986 | "statuses": "2.0.1" 1987 | }, 1988 | "engines": { 1989 | "node": ">= 0.8.0" 1990 | } 1991 | }, 1992 | "node_modules/send/node_modules/ms": { 1993 | "version": "2.1.3", 1994 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1995 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 1996 | }, 1997 | "node_modules/serve-static": { 1998 | "version": "1.15.0", 1999 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", 2000 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", 2001 | "dependencies": { 2002 | "encodeurl": "~1.0.2", 2003 | "escape-html": "~1.0.3", 2004 | "parseurl": "~1.3.3", 2005 | "send": "0.18.0" 2006 | }, 2007 | "engines": { 2008 | "node": ">= 0.8.0" 2009 | } 2010 | }, 2011 | "node_modules/setprototypeof": { 2012 | "version": "1.2.0", 2013 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 2014 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 2015 | }, 2016 | "node_modules/shebang-command": { 2017 | "version": "2.0.0", 2018 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 2019 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 2020 | "dev": true, 2021 | "dependencies": { 2022 | "shebang-regex": "^3.0.0" 2023 | }, 2024 | "engines": { 2025 | "node": ">=8" 2026 | } 2027 | }, 2028 | "node_modules/shebang-regex": { 2029 | "version": "3.0.0", 2030 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 2031 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 2032 | "dev": true, 2033 | "engines": { 2034 | "node": ">=8" 2035 | } 2036 | }, 2037 | "node_modules/side-channel": { 2038 | "version": "1.0.4", 2039 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", 2040 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", 2041 | "dependencies": { 2042 | "call-bind": "^1.0.0", 2043 | "get-intrinsic": "^1.0.2", 2044 | "object-inspect": "^1.9.0" 2045 | }, 2046 | "funding": { 2047 | "url": "https://github.com/sponsors/ljharb" 2048 | } 2049 | }, 2050 | "node_modules/source-map-js": { 2051 | "version": "1.0.2", 2052 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", 2053 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", 2054 | "engines": { 2055 | "node": ">=0.10.0" 2056 | } 2057 | }, 2058 | "node_modules/split": { 2059 | "version": "0.3.3", 2060 | "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", 2061 | "integrity": "sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==", 2062 | "dev": true, 2063 | "dependencies": { 2064 | "through": "2" 2065 | }, 2066 | "engines": { 2067 | "node": "*" 2068 | } 2069 | }, 2070 | "node_modules/statuses": { 2071 | "version": "2.0.1", 2072 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 2073 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", 2074 | "engines": { 2075 | "node": ">= 0.8" 2076 | } 2077 | }, 2078 | "node_modules/stream-combiner": { 2079 | "version": "0.0.4", 2080 | "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", 2081 | "integrity": "sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==", 2082 | "dev": true, 2083 | "dependencies": { 2084 | "duplexer": "~0.1.1" 2085 | } 2086 | }, 2087 | "node_modules/string-argv": { 2088 | "version": "0.3.1", 2089 | "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", 2090 | "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", 2091 | "dev": true, 2092 | "engines": { 2093 | "node": ">=0.6.19" 2094 | } 2095 | }, 2096 | "node_modules/string-width": { 2097 | "version": "4.2.3", 2098 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 2099 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 2100 | "dependencies": { 2101 | "emoji-regex": "^8.0.0", 2102 | "is-fullwidth-code-point": "^3.0.0", 2103 | "strip-ansi": "^6.0.1" 2104 | }, 2105 | "engines": { 2106 | "node": ">=8" 2107 | } 2108 | }, 2109 | "node_modules/strip-ansi": { 2110 | "version": "6.0.1", 2111 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 2112 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 2113 | "dependencies": { 2114 | "ansi-regex": "^5.0.1" 2115 | }, 2116 | "engines": { 2117 | "node": ">=8" 2118 | } 2119 | }, 2120 | "node_modules/through": { 2121 | "version": "2.3.8", 2122 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 2123 | "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", 2124 | "dev": true 2125 | }, 2126 | "node_modules/toidentifier": { 2127 | "version": "1.0.1", 2128 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 2129 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 2130 | "engines": { 2131 | "node": ">=0.6" 2132 | } 2133 | }, 2134 | "node_modules/tsc-watch": { 2135 | "version": "6.0.0", 2136 | "resolved": "https://registry.npmjs.org/tsc-watch/-/tsc-watch-6.0.0.tgz", 2137 | "integrity": "sha512-zgpju+/z5z29/kK5V28Nz16CMkX2voFOUxkTlCim/R25hxzbyUqu2NfTnmJBQfESBSPbEQUGqDdB9A8opAcB4A==", 2138 | "dev": true, 2139 | "dependencies": { 2140 | "cross-spawn": "^7.0.3", 2141 | "node-cleanup": "^2.1.2", 2142 | "ps-tree": "^1.2.0", 2143 | "string-argv": "^0.3.1" 2144 | }, 2145 | "bin": { 2146 | "tsc-watch": "dist/lib/tsc-watch.js" 2147 | }, 2148 | "engines": { 2149 | "node": ">=12.12.0" 2150 | }, 2151 | "peerDependencies": { 2152 | "typescript": "*" 2153 | } 2154 | }, 2155 | "node_modules/type-is": { 2156 | "version": "1.6.18", 2157 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 2158 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 2159 | "dependencies": { 2160 | "media-typer": "0.3.0", 2161 | "mime-types": "~2.1.24" 2162 | }, 2163 | "engines": { 2164 | "node": ">= 0.6" 2165 | } 2166 | }, 2167 | "node_modules/typescript": { 2168 | "version": "5.2.2", 2169 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", 2170 | "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", 2171 | "devOptional": true, 2172 | "bin": { 2173 | "tsc": "bin/tsc", 2174 | "tsserver": "bin/tsserver" 2175 | }, 2176 | "engines": { 2177 | "node": ">=14.17" 2178 | } 2179 | }, 2180 | "node_modules/unpipe": { 2181 | "version": "1.0.0", 2182 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 2183 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", 2184 | "engines": { 2185 | "node": ">= 0.8" 2186 | } 2187 | }, 2188 | "node_modules/use-sync-external-store": { 2189 | "version": "1.2.0", 2190 | "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", 2191 | "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", 2192 | "peerDependencies": { 2193 | "react": "^16.8.0 || ^17.0.0 || ^18.0.0" 2194 | } 2195 | }, 2196 | "node_modules/utils-merge": { 2197 | "version": "1.0.1", 2198 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 2199 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", 2200 | "engines": { 2201 | "node": ">= 0.4.0" 2202 | } 2203 | }, 2204 | "node_modules/vary": { 2205 | "version": "1.1.2", 2206 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 2207 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", 2208 | "engines": { 2209 | "node": ">= 0.8" 2210 | } 2211 | }, 2212 | "node_modules/vue": { 2213 | "version": "3.3.4", 2214 | "resolved": "https://registry.npmjs.org/vue/-/vue-3.3.4.tgz", 2215 | "integrity": "sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==", 2216 | "dependencies": { 2217 | "@vue/compiler-dom": "3.3.4", 2218 | "@vue/compiler-sfc": "3.3.4", 2219 | "@vue/runtime-dom": "3.3.4", 2220 | "@vue/server-renderer": "3.3.4", 2221 | "@vue/shared": "3.3.4" 2222 | } 2223 | }, 2224 | "node_modules/vue-demi": { 2225 | "version": "0.14.6", 2226 | "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz", 2227 | "integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==", 2228 | "hasInstallScript": true, 2229 | "bin": { 2230 | "vue-demi-fix": "bin/vue-demi-fix.js", 2231 | "vue-demi-switch": "bin/vue-demi-switch.js" 2232 | }, 2233 | "engines": { 2234 | "node": ">=12" 2235 | }, 2236 | "funding": { 2237 | "url": "https://github.com/sponsors/antfu" 2238 | }, 2239 | "peerDependencies": { 2240 | "@vue/composition-api": "^1.0.0-rc.1", 2241 | "vue": "^3.0.0-0 || ^2.6.0" 2242 | }, 2243 | "peerDependenciesMeta": { 2244 | "@vue/composition-api": { 2245 | "optional": true 2246 | } 2247 | } 2248 | }, 2249 | "node_modules/vue-router": { 2250 | "version": "4.2.4", 2251 | "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.2.4.tgz", 2252 | "integrity": "sha512-9PISkmaCO02OzPVOMq2w82ilty6+xJmQrarYZDkjZBfl4RvYAlt4PKnEX21oW4KTtWfa9OuO/b3qk1Od3AEdCQ==", 2253 | "dependencies": { 2254 | "@vue/devtools-api": "^6.5.0" 2255 | }, 2256 | "funding": { 2257 | "url": "https://github.com/sponsors/posva" 2258 | }, 2259 | "peerDependencies": { 2260 | "vue": "^3.2.0" 2261 | } 2262 | }, 2263 | "node_modules/which": { 2264 | "version": "2.0.2", 2265 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 2266 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 2267 | "dev": true, 2268 | "dependencies": { 2269 | "isexe": "^2.0.0" 2270 | }, 2271 | "bin": { 2272 | "node-which": "bin/node-which" 2273 | }, 2274 | "engines": { 2275 | "node": ">= 8" 2276 | } 2277 | }, 2278 | "node_modules/wrap-ansi": { 2279 | "version": "7.0.0", 2280 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 2281 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 2282 | "dependencies": { 2283 | "ansi-styles": "^4.0.0", 2284 | "string-width": "^4.1.0", 2285 | "strip-ansi": "^6.0.0" 2286 | }, 2287 | "engines": { 2288 | "node": ">=10" 2289 | }, 2290 | "funding": { 2291 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 2292 | } 2293 | }, 2294 | "node_modules/ws": { 2295 | "version": "8.14.2", 2296 | "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", 2297 | "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", 2298 | "engines": { 2299 | "node": ">=10.0.0" 2300 | }, 2301 | "peerDependencies": { 2302 | "bufferutil": "^4.0.1", 2303 | "utf-8-validate": ">=5.0.2" 2304 | }, 2305 | "peerDependenciesMeta": { 2306 | "bufferutil": { 2307 | "optional": true 2308 | }, 2309 | "utf-8-validate": { 2310 | "optional": true 2311 | } 2312 | } 2313 | }, 2314 | "node_modules/y18n": { 2315 | "version": "5.0.8", 2316 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", 2317 | "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", 2318 | "engines": { 2319 | "node": ">=10" 2320 | } 2321 | }, 2322 | "node_modules/yaml": { 2323 | "version": "2.2.1", 2324 | "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.2.1.tgz", 2325 | "integrity": "sha512-e0WHiYql7+9wr4cWMx3TVQrNwejKaEe7/rHNmQmqRjazfOP5W8PB6Jpebb5o6fIapbz9o9+2ipcaTM2ZwDI6lw==", 2326 | "engines": { 2327 | "node": ">= 14" 2328 | } 2329 | }, 2330 | "node_modules/yargs": { 2331 | "version": "17.7.2", 2332 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", 2333 | "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", 2334 | "dependencies": { 2335 | "cliui": "^8.0.1", 2336 | "escalade": "^3.1.1", 2337 | "get-caller-file": "^2.0.5", 2338 | "require-directory": "^2.1.1", 2339 | "string-width": "^4.2.3", 2340 | "y18n": "^5.0.5", 2341 | "yargs-parser": "^21.1.1" 2342 | }, 2343 | "engines": { 2344 | "node": ">=12" 2345 | } 2346 | }, 2347 | "node_modules/yargs-parser": { 2348 | "version": "21.1.1", 2349 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", 2350 | "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", 2351 | "engines": { 2352 | "node": ">=12" 2353 | } 2354 | }, 2355 | "node_modules/zustand": { 2356 | "version": "4.4.1", 2357 | "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.4.1.tgz", 2358 | "integrity": "sha512-QCPfstAS4EBiTQzlaGP1gmorkh/UL1Leaj2tdj+zZCZ/9bm0WS7sI2wnfD5lpOszFqWJ1DcPnGoY8RDL61uokw==", 2359 | "dependencies": { 2360 | "use-sync-external-store": "1.2.0" 2361 | }, 2362 | "engines": { 2363 | "node": ">=12.7.0" 2364 | }, 2365 | "peerDependencies": { 2366 | "@types/react": ">=16.8", 2367 | "immer": ">=9.0", 2368 | "react": ">=16.8" 2369 | }, 2370 | "peerDependenciesMeta": { 2371 | "@types/react": { 2372 | "optional": true 2373 | }, 2374 | "immer": { 2375 | "optional": true 2376 | }, 2377 | "react": { 2378 | "optional": true 2379 | } 2380 | } 2381 | } 2382 | } 2383 | } 2384 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@markwhen/mw", 3 | "version": "1.2.4", 4 | "description": "CLI for markwhen documents", 5 | "type": "module", 6 | "bin": { 7 | "mw": "lib/index.js" 8 | }, 9 | "scripts": { 10 | "build": "tsc && node build.js", 11 | "test": "echo \"Error: no test specified\" && exit 1", 12 | "watch": "tsc-watch", 13 | "link:parser": "yalc add @markwhen/parser && yalc link @markwhen/parser && npm install", 14 | "unlink:parser": "yalc remove @markwhen/parser && npm install" 15 | }, 16 | "keywords": [], 17 | "author": "", 18 | "license": "MIT", 19 | "devDependencies": { 20 | "@types/express": "^4.17.17", 21 | "@types/luxon": "^3.3.2", 22 | "@types/node": "^18.15.5", 23 | "@types/ws": "^8.5.4", 24 | "@types/yargs": "^17.0.23", 25 | "esbuild": "^0.17.12", 26 | "tsc-watch": "^6.0.0", 27 | "typescript": "^5.2.2" 28 | }, 29 | "dependencies": { 30 | "@markwhen/calendar": "^1.3.4", 31 | "@markwhen/parser": "^0.10.14", 32 | "@markwhen/resume": "^1.1.0", 33 | "@markwhen/timeline": "^1.3.0", 34 | "@nuxt/devalue": "^2.0.2", 35 | "express": "^4.18.2", 36 | "ical.js": "^1.5.0", 37 | "node-html-parser": "^6.1.10", 38 | "ws": "^8.14.2", 39 | "yargs": "^17.7.2" 40 | }, 41 | "files": [ 42 | "lib/**/*", 43 | "view-templates/**/*" 44 | ] 45 | } 46 | -------------------------------------------------------------------------------- /src/dateTimeUtilities.ts: -------------------------------------------------------------------------------- 1 | import { DateTime, type DurationUnits } from "luxon"; 2 | import { 3 | AMERICAN_DATE_FORMAT, 4 | DateRangePart, 5 | EUROPEAN_DATE_FORMAT, 6 | Event, 7 | toDateRange, 8 | type DateFormat, 9 | type DateRange, 10 | type SomeNode, 11 | isEventNode, 12 | eventValue, 13 | } from "@markwhen/parser"; 14 | 15 | export enum Weight { 16 | SECOND = 0, 17 | QUARTER_MINUTE = 1, 18 | MINUTE = 2, 19 | QUARTER_HOUR = 3, 20 | HOUR = 4, 21 | DAY = 5, 22 | MONTH = 6, 23 | YEAR = 7, 24 | DECADE = 8, 25 | CENT = 9, 26 | } 27 | 28 | export type DisplayScale = 29 | | "second" 30 | | "quarterminute" 31 | | "minute" 32 | | "quarterhour" 33 | | "hour" 34 | | "day" 35 | | "month" 36 | | "year" 37 | | "decade" 38 | | "cent"; 39 | 40 | export const scales: DisplayScale[] = [ 41 | "second", 42 | "quarterminute", 43 | "minute", 44 | "quarterhour", 45 | "hour", 46 | "day", 47 | "month", 48 | "year", 49 | "decade", 50 | "cent", 51 | ]; 52 | 53 | export function dateScale(dateTime: DateTime) { 54 | if (dateTime.second === 0) { 55 | if (dateTime.minute === 0) { 56 | if (dateTime.hour === 0) { 57 | if (dateTime.day === 1) { 58 | if (dateTime.month === 1) { 59 | if (dateTime.year % 100 === 0) { 60 | return Weight.CENT; 61 | } 62 | if (dateTime.year % 10 === 0) { 63 | return Weight.DECADE; 64 | } 65 | return Weight.YEAR; 66 | } 67 | return Weight.MONTH; 68 | } 69 | return Weight.DAY; 70 | } 71 | return Weight.HOUR; 72 | } else if (dateTime.minute % 15 == 0) { 73 | return Weight.QUARTER_HOUR; 74 | } 75 | return Weight.MINUTE; 76 | } else if (dateTime.second % 15 === 0) { 77 | return Weight.QUARTER_MINUTE; 78 | } 79 | return Weight.SECOND; 80 | } 81 | 82 | export const viewportLeftMarginPixels = 64; 83 | export const diffScale = "hours"; 84 | 85 | export interface DateInterval { 86 | from: DateTime; 87 | to: DateTime; 88 | } 89 | 90 | export function floorDateTime(dateTime: DateTime, toScale: DisplayScale) { 91 | const year = dateTime.year; 92 | if (toScale === "cent") { 93 | const roundedYear = year - (year % 100); 94 | return DateTime.fromObject({ year: roundedYear }); 95 | } 96 | if (toScale === "decade") { 97 | const roundedYear = year - (year % 10); 98 | return DateTime.fromObject({ year: roundedYear }); 99 | } 100 | if (toScale === "year") { 101 | return DateTime.fromObject({ year }); 102 | } 103 | const month = dateTime.month; 104 | if (toScale === "month") { 105 | return DateTime.fromObject({ year, month }); 106 | } 107 | const day = dateTime.day; 108 | if (toScale === "day") { 109 | return DateTime.fromObject({ year, month, day }); 110 | } 111 | const hour = dateTime.hour; 112 | if (toScale === "hour") { 113 | return DateTime.fromObject({ year, month, day, hour }); 114 | } 115 | const minute = dateTime.minute; 116 | if (toScale === "quarterhour") { 117 | return DateTime.fromObject({ 118 | year, 119 | month, 120 | day, 121 | hour, 122 | minute: minute - (minute % 15), 123 | }); 124 | } 125 | const second = dateTime.second; 126 | if (toScale === "quarterminute") { 127 | return DateTime.fromObject({ 128 | year, 129 | month, 130 | day, 131 | hour, 132 | minute, 133 | second: second - (second % 15), 134 | }); 135 | } 136 | if (toScale === "minute") { 137 | return DateTime.fromObject({ year, month, day, hour, minute }); 138 | } 139 | return DateTime.fromObject({ year, month, day, hour, minute, second }); 140 | } 141 | 142 | export function ceilDateTime(dateTime: DateTime, toScale: DisplayScale) { 143 | let increment; 144 | if (toScale === "cent") { 145 | increment = { years: 100 }; 146 | } else if (toScale === "decade") { 147 | increment = { years: 10 }; 148 | } else if (toScale === "quarterhour") { 149 | increment = { minutes: 15 }; 150 | } else if (toScale === "quarterminute") { 151 | increment = { seconds: 15 }; 152 | } else { 153 | increment = { [toScale]: 1 }; 154 | } 155 | const ceiled = floorDateTime(dateTime, toScale).plus(increment); 156 | return ceiled; 157 | } 158 | 159 | export function roundDateTime(dateTime: DateTime, toScale: DisplayScale) { 160 | const up = ceilDateTime(dateTime, toScale); 161 | const down = floorDateTime(dateTime, toScale); 162 | const upDiff = dateTime.diff(up); 163 | const downDiff = dateTime.diff(down); 164 | return Math.abs(+upDiff) < Math.abs(+downDiff) ? up : down; 165 | } 166 | 167 | export interface DateTimeAndOffset { 168 | dateTime: DateTime; 169 | left: number; 170 | } 171 | 172 | export type OffsetRange = [DateTimeAndOffset, DateTimeAndOffset]; 173 | 174 | export const humanDuration = (range: DateRange): string => { 175 | const units: DurationUnits = [ 176 | "years", 177 | "months", 178 | "days", 179 | "hours", 180 | "minutes", 181 | "seconds", 182 | ]; 183 | const diff = range.toDateTime.diff(range.fromDateTime, units); 184 | let adjustedUnits = units.filter((u) => diff.get(u) > 0); 185 | return adjustedUnits.length 186 | ? range.toDateTime.diff(range.fromDateTime, adjustedUnits).toHuman() 187 | : "instant"; 188 | }; 189 | 190 | export const eventHumanDuration = (e: Event): string => 191 | humanDuration(toDateRange(e.dateRangeIso)); 192 | 193 | export const scaleForDuration = (dateRange: DateRangePart): DisplayScale => { 194 | const diff = dateRange.toDateTime.diff(dateRange.fromDateTime).as("seconds"); 195 | if (diff < 60) { 196 | return "second"; 197 | } 198 | if (diff < 60 * 60) { 199 | return "minute"; 200 | } 201 | if (diff < 60 * 60 * 24) { 202 | return "hour"; 203 | } 204 | if (diff < 60 * 60 * 24 * 30) { 205 | return "day"; 206 | } 207 | if (diff < 60 * 60 * 24 * 30 * 12) { 208 | return "month"; 209 | } 210 | return "year"; 211 | }; 212 | 213 | function isAtLeastDaySpecificDate( 214 | dateTime: DateTime, 215 | scale: DisplayScale 216 | ): boolean { 217 | return ( 218 | isDayStartOrEnd(dateTime, scale) || 219 | isMonthStartOrEnd(dateTime, scale) || 220 | isYearStartOrEnd(dateTime, scale) 221 | ); 222 | } 223 | 224 | function isAtLeastDaySpecificRange( 225 | range: DateRange, 226 | scale: DisplayScale 227 | ): boolean { 228 | return ( 229 | isAtLeastDaySpecificDate(range.fromDateTime, scale) && 230 | isAtLeastDaySpecificDate(range.toDateTime, scale) 231 | ); 232 | } 233 | 234 | export function dateRangeToString( 235 | range: DateRange, 236 | scale: DisplayScale, 237 | dateFormat: DateFormat | undefined 238 | ) { 239 | if (isAtLeastDaySpecificRange(range, scale)) { 240 | const fromAsString = dateTimeToString( 241 | range.fromDateTime, 242 | scale, 243 | true, 244 | dateFormat 245 | ); 246 | const toAsString = dateTimeToString( 247 | range.toDateTime, 248 | scale, 249 | false, 250 | dateFormat 251 | ); 252 | if ( 253 | fromAsString === toAsString || 254 | range.fromDateTime === range.toDateTime 255 | ) { 256 | return `${fromAsString}`; 257 | } 258 | return dateFormat 259 | ? `${fromAsString} - ${toAsString}` 260 | : `${fromAsString}/${toAsString}`; 261 | } 262 | return `${asIso(range.fromDateTime)} - ${asIso(range.toDateTime)}`; 263 | } 264 | 265 | export const eventMidpoint = (node: SomeNode): DateTime | undefined => { 266 | if (isEventNode(node)) { 267 | return dateMidpoint(toDateRange(eventValue(node).dateRangeIso)); 268 | } else { 269 | if (!node.range || !node.range.fromDateTime || !node.range.toDateTime) 270 | return undefined; 271 | } 272 | return dateMidpoint(node.range); 273 | }; 274 | 275 | export const dateMidpoint = (range: DateRange): DateTime => { 276 | return range.fromDateTime.plus({ 277 | seconds: range.toDateTime.diff(range.fromDateTime).as("seconds") / 2, 278 | }); 279 | }; 280 | 281 | function isMinuteStartOrEnd(dateTime: DateTime, scale: DisplayScale) { 282 | if (!["day", "hour", "minute", "second"].includes(scale)) { 283 | return false; 284 | } 285 | return [57, 58, 59, 0, 1, 2, 3].includes(dateTime.second); 286 | } 287 | 288 | function isDayStartOrEnd(dateTime: DateTime, scale: DisplayScale) { 289 | if (!["month", "day"].includes(scale)) { 290 | return false; 291 | } 292 | return [23, 0, 1].includes(dateTime.hour); 293 | } 294 | 295 | function isMonthStartOrEnd(dateTime: DateTime, scale: DisplayScale) { 296 | if (!["decade", "year", "month"].includes(scale)) { 297 | return false; 298 | } 299 | return [28, 29, 30, 31, 1, 2].includes(dateTime.day); 300 | } 301 | 302 | function isYearStartOrEnd(dateTime: DateTime, scale: DisplayScale): boolean { 303 | if (!["cent", "decade", "year", "month"].includes(scale)) { 304 | return false; 305 | } 306 | if (dateTime.month === 12 && (dateTime.day === 31 || dateTime.day === 30)) { 307 | return true; 308 | } 309 | if (dateTime.month === 1 && (dateTime.day === 1 || dateTime.day === 2)) { 310 | return true; 311 | } 312 | return false; 313 | } 314 | 315 | function dateTimeToString( 316 | dateTime: DateTime, 317 | scale: DisplayScale, 318 | isStartDate: boolean, 319 | dateFormat: DateFormat | undefined 320 | ): string | undefined { 321 | if (isYearStartOrEnd(dateTime, scale)) { 322 | if (isStartDate) { 323 | const fromYear = dateTime.plus({ days: 2 }).year; 324 | return `${fromYear}`; 325 | } else { 326 | const toYear = dateTime.minus({ days: 2 }).year; 327 | return `${toYear}`; 328 | } 329 | } 330 | if (isMonthStartOrEnd(dateTime, scale)) { 331 | if (isStartDate) { 332 | const adjustedForward = dateTime.plus({ days: 2 }); 333 | const adjustedMonth = 334 | adjustedForward.month < 10 335 | ? "0" + adjustedForward.month 336 | : adjustedForward.month; 337 | return dateFormat 338 | ? `${adjustedMonth}/${adjustedForward.year}` 339 | : `${adjustedForward.year}-${adjustedMonth}`; 340 | } else { 341 | const adjustedBack = dateTime.minus({ days: 2 }); 342 | const adjustedMonth = 343 | adjustedBack.month < 10 ? "0" + adjustedBack.month : adjustedBack.month; 344 | return dateFormat 345 | ? `${adjustedMonth}/${adjustedBack.year}` 346 | : `${adjustedBack.year}-${adjustedMonth}`; 347 | } 348 | } 349 | if (isDayStartOrEnd(dateTime, scale)) { 350 | if (isStartDate) { 351 | const adjustedForward = dateTime.plus({ hours: 2 }); 352 | return dateFormat 353 | ? dayFormat(adjustedForward, dateFormat) 354 | : adjustedForward.toISODate() || undefined; 355 | } else { 356 | const adjustedBack = dateTime.minus({ hours: 2 }); 357 | return dateFormat 358 | ? dayFormat(adjustedBack, dateFormat) 359 | : adjustedBack.toISODate() || undefined; 360 | } 361 | } 362 | } 363 | 364 | function dayFormat(dateTime: DateTime, dateFormat: DateFormat): string { 365 | const day = dateTime.day; 366 | const month = dateTime.month; 367 | const year = dateTime.year; 368 | if (dateFormat === AMERICAN_DATE_FORMAT) { 369 | return `${month}/${day}/${year}`; 370 | } else if (dateFormat === EUROPEAN_DATE_FORMAT) { 371 | return `${day}/${month}/${year}`; 372 | } 373 | return "unexpected date format"; 374 | } 375 | 376 | function asIso(dateTime: DateTime): string { 377 | return dateTime.toUTC().toISO({ includeOffset: false }) + "Z"; 378 | } 379 | -------------------------------------------------------------------------------- /src/ical.d.ts: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: © 2019 EteSync Authors 2 | // SPDX-License-Identifier: MPL-2.0 3 | 4 | declare module "ical.js" { 5 | function parse(input: string): unknown[]; 6 | 7 | export class helpers { 8 | public updateTimezones(vcal: Component): Component; 9 | } 10 | 11 | class Component { 12 | public fromString(str: string): Component; 13 | 14 | public name: string; 15 | 16 | constructor(jCal: unknown[] | string, parent?: Component); 17 | 18 | public toJSON(): unknown[]; 19 | 20 | public getFirstSubcomponent(name?: string): Component | null; 21 | public getAllSubcomponents(name?: string): Component[]; 22 | 23 | public getFirstPropertyValue(name?: string): T; 24 | 25 | public getFirstProperty(name?: string): Property; 26 | public getAllProperties(name?: string): Property[]; 27 | 28 | public addProperty(property: Property): Property; 29 | public addPropertyWithValue(name: string, value: string | number | Record): Property; 30 | 31 | public hasProperty(name?: string): boolean; 32 | 33 | public updatePropertyWithValue(name: string, value: string | number | Record): Property; 34 | 35 | public removeAllProperties(name?: string): boolean; 36 | 37 | public addSubcomponent(component: Component): Component; 38 | } 39 | 40 | export class Event { 41 | public uid: string; 42 | public summary: string; 43 | public startDate: Time; 44 | public endDate: Time; 45 | public description: string; 46 | public location: string; 47 | public attendees: Property[]; 48 | /** 49 | * The sequence value for this event. Used for scheduling. 50 | * 51 | * @type {number} 52 | * @memberof Event 53 | */ 54 | public sequence: number; 55 | /** 56 | * The duration. This can be the result directly from the property, or the 57 | * duration calculated from start date and end date. Setting the property 58 | * will remove unknown `dtend` properties. 59 | * 60 | * @type {Duration} 61 | * @memberof Event 62 | */ 63 | public duration: Duration; 64 | /** 65 | * The organizer value as an uri. In most cases this is a mailto: uri, 66 | * but it can also be something else, like urn:uuid:... 67 | */ 68 | public organizer: string; 69 | 70 | /** The recurrence id for this event */ 71 | public recurrenceId: Time; 72 | 73 | public component: Component; 74 | 75 | public constructor( 76 | component?: Component | null, 77 | options?: { strictExceptions: boolean; exepctions: Array } 78 | ); 79 | 80 | public isRecurring(): boolean; 81 | public iterator(startTime?: Time): RecurExpansion; 82 | public getOccurrenceDetails(occurrence: Time): OccurrenceDetails; 83 | public getRecurrenceTypes(): FrequencyValues; 84 | } 85 | 86 | // https://mozilla-comm.github.io/ical.js/api/ICAL.Event.html#.occurrenceDetails 87 | interface OccurrenceDetails { 88 | recurrenceId: Time; 89 | item: Event; 90 | startDate: Time; 91 | endDate: Time; 92 | } 93 | 94 | export class Property { 95 | public name: string; 96 | public type: string; 97 | 98 | constructor(jCal: unknown[] | string, parent?: Component); 99 | 100 | public getFirstValue(): T; 101 | public getValues(): T[]; 102 | 103 | public setParameter(name: string, value: string | string[]): void; 104 | public setValue(value: string | Record): void; 105 | public setValues(values: (string | Record)[]): void; 106 | public toJSON(): unknown; 107 | } 108 | 109 | interface TimeJsonData { 110 | year?: number; 111 | month?: number; 112 | day?: number; 113 | hour?: number; 114 | minute?: number; 115 | second?: number; 116 | isDate?: boolean; 117 | } 118 | 119 | export class Time { 120 | public static fromString(str: string): Time; 121 | public static fromJSDate(aDate: Date | null, useUTC: boolean): Time; 122 | public static fromData(aData: TimeJsonData): Time; 123 | public static fromDateTimeString(aDate: string): Time; 124 | 125 | public now(): Time; 126 | 127 | public isDate: boolean; 128 | public timezone: string; 129 | public zone: Timezone; 130 | 131 | public year: number; 132 | public month: number; 133 | public day: number; 134 | public hour: number; 135 | public minute: number; 136 | public second: number; 137 | 138 | constructor(data?: TimeJsonData); 139 | public compare(aOther: Time): number; 140 | 141 | public clone(): Time; 142 | public convertToZone(zone: Timezone): Time; 143 | 144 | public adjust( 145 | aExtraDays: number, 146 | aExtraHours: number, 147 | aExtraMinutes: number, 148 | aExtraSeconds: number, 149 | aTimeopt?: Time 150 | ): void; 151 | 152 | public addDuration(aDuration: Duration): void; 153 | public subtractDateTz(aDate: Time): Duration; 154 | 155 | public toUnixTime(): number; 156 | public toJSDate(): Date; 157 | public toJSON(): TimeJsonData; 158 | public get icaltype(): "date" | "date-time"; 159 | } 160 | 161 | export class Duration { 162 | public weeks: number; 163 | public days: number; 164 | public hours: number; 165 | public minutes: number; 166 | public seconds: number; 167 | public isNegative: boolean; 168 | public icalclass: string; 169 | public icaltype: string; 170 | } 171 | 172 | export class RecurExpansion { 173 | public complete: boolean; 174 | public dtstart: Time; 175 | public last: Time; 176 | public next(): Time; 177 | public fromData(options: any): RecurExpansion; 178 | public toJSON(): any; 179 | constructor(options: { 180 | /** Start time of the event */ 181 | dtstart: Time; 182 | /** Component for expansion, required if not resuming. */ 183 | component?: Component; 184 | }); 185 | } 186 | 187 | export class Timezone { 188 | public utcTimezone: Timezone; 189 | public localTimezone: Timezone; 190 | public convert_time(tt: Time, fromZone: Timezone, toZone: Timezone): Time; 191 | 192 | public tzid: string; 193 | public component: Component; 194 | 195 | constructor( 196 | data: 197 | | Component 198 | | { 199 | component: string | Component; 200 | tzid?: string; 201 | location?: string; 202 | tznames?: string; 203 | latitude?: number; 204 | longitude?: number; 205 | } 206 | ); 207 | } 208 | 209 | export class TimezoneService { 210 | public get(tzid: string): Timezone | null; 211 | public has(tzid: string): boolean; 212 | public register(tzid: string, zone: Timezone | Component): void; 213 | public remove(tzid: string): Timezone | null; 214 | } 215 | 216 | export type FrequencyValues = 217 | | "YEARLY" 218 | | "MONTHLY" 219 | | "WEEKLY" 220 | | "DAILY" 221 | | "HOURLY" 222 | | "MINUTELY" 223 | | "SECONDLY"; 224 | 225 | export enum WeekDay { 226 | SU = 1, 227 | MO, 228 | TU, 229 | WE, 230 | TH, 231 | FR, 232 | SA, 233 | } 234 | 235 | export class RecurData { 236 | public freq?: FrequencyValues; 237 | public interval?: number; 238 | public wkst?: WeekDay; 239 | public until?: Time; 240 | public count?: number; 241 | public bysecond?: number[] | number; 242 | public byminute?: number[] | number; 243 | public byhour?: number[] | number; 244 | public byday?: string[] | string; 245 | public bymonthday?: number[] | number; 246 | public byyearday?: number[] | number; 247 | public byweekno?: number[] | number; 248 | public bymonth?: number[] | number; 249 | public bysetpos?: number[] | number; 250 | } 251 | 252 | export class RecurIterator { 253 | public next(): Time; 254 | } 255 | 256 | export class Recur { 257 | constructor(data?: RecurData); 258 | public until: Time | null; 259 | public freq: FrequencyValues; 260 | public count: number | null; 261 | 262 | public clone(): Recur; 263 | public toJSON(): Omit & { until?: string }; 264 | public iterator(startTime?: Time): RecurIterator; 265 | public isByCount(): boolean; 266 | } 267 | } -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import yargs from "yargs"; 4 | import { hideBin } from "yargs/helpers"; 5 | import { parse, Timelines } from "@markwhen/parser"; 6 | import { readFileSync, writeFileSync, watch } from "fs"; 7 | import { fileURLToPath } from "url"; 8 | import path from "path"; 9 | import express from "express"; 10 | import { parse as parseHtml } from "node-html-parser"; 11 | import { WebSocketServer } from "ws"; 12 | import ICAL from "ical.js"; 13 | import { DateTime } from "luxon"; 14 | import { dateRangeToString } from "./dateTimeUtilities.js"; 15 | 16 | const er = (m: string) => { 17 | process.stderr.write(m); 18 | process.exit(1); 19 | }; 20 | 21 | type ViewType = "timeline" | "calendar" | "resume" | "json"; 22 | 23 | const argv = yargs(hideBin(process.argv)) 24 | .usage("$0 [-o ] [-d ]") 25 | .option("outputType", { 26 | alias: "o", 27 | choices: ["json", "timeline", "calendar", "resume"], 28 | desc: 'Output type. Defaults to simply parsing the document and returning json. Specify a view like "timeline" to produce an html document.', 29 | }) 30 | .option("destination", { 31 | alias: "d", 32 | string: true, 33 | description: 34 | 'Output destination, e.g., "timeline.html". If "output" is not specified, will infer the output from the filename. For example, "MyTimeline.json" will produce json, "product_calendar.html" will produce the calendar view, "personal_timeline.html" will produce the timeline view, etc.', 35 | }) 36 | .option("port", { 37 | alias: "p", 38 | number: true, 39 | description: "If serving, port to serve from", 40 | default: 3000, 41 | }) 42 | .option("socketPort", { 43 | alias: "s", 44 | number: true, 45 | desc: "If serving, port to serve socket from", 46 | default: 3001, 47 | }) 48 | .demandCommand(1, "Provide an input markwhen file").argv; 49 | 50 | function getParseFromFile(inputFileName: string | number) { 51 | const content = readFileSync(inputFileName, "utf-8"); 52 | const parsed = parse(content); 53 | return { parsed, rawText: content }; 54 | } 55 | 56 | function injectScript(domString: string, jsToInject: string) { 57 | const html = parseHtml(domString); 58 | const script = ``; 59 | const head = html.getElementsByTagName("head")[0]; 60 | head.innerHTML = script + head.innerHTML; 61 | return html.toString(); 62 | } 63 | 64 | function templateHtml(viewType: Exclude) { 65 | const currentPath = path.dirname(fileURLToPath(import.meta.url)); 66 | const templateHtml = readFileSync( 67 | path.resolve(currentPath, `../view-templates/${viewType}.html`), 68 | "utf-8" 69 | ); 70 | return templateHtml; 71 | } 72 | 73 | const appState = (parsed: Timelines, rawText: string) => ({ 74 | rawText, 75 | parsed: parsed.timelines, 76 | transformed: parsed.timelines[0].events, 77 | }); 78 | 79 | function getInitialHtml( 80 | parsed: Timelines, 81 | rawText: string, 82 | viewType: ViewType 83 | ) { 84 | if (viewType === "json") { 85 | return JSON.stringify(parsed); 86 | } 87 | 88 | return injectScript( 89 | templateHtml(viewType), 90 | `var __markwhen_initial_state = ${JSON.stringify( 91 | appState(parsed, rawText) 92 | )}` 93 | ); 94 | } 95 | 96 | async function main() { 97 | const args = await argv; 98 | let inputFileName = "" + args._[0]; 99 | let serving = false; 100 | if (inputFileName === "serve") { 101 | serving = true; 102 | inputFileName = "" + args._[1]; 103 | if (!inputFileName) { 104 | er("Provide an input markwhen file"); 105 | } 106 | } 107 | 108 | if ( 109 | [".ical", ".ics", ".ifb", ".icalendar"].some((ext) => 110 | inputFileName.endsWith(ext) 111 | ) 112 | ) { 113 | // is ical 114 | const content = readFileSync(inputFileName, "utf-8"); 115 | let markwhenText = ""; 116 | const icalParse = ICAL.parse(content); 117 | const component = new ICAL.Component(icalParse); 118 | const vevents = component.getAllSubcomponents("vevent"); 119 | for (const vevent of vevents) { 120 | const event = new ICAL.Event(vevent); 121 | 122 | const timezone = 123 | component 124 | .getFirstSubcomponent("vtimezone") 125 | ?.getFirstPropertyValue("tzid") || ""; 126 | 127 | const fromDateTime = timezone 128 | ? DateTime.fromISO(event.startDate.toString(), { zone: timezone }) 129 | : DateTime.fromMillis(event.startDate.toUnixTime() * 1000); 130 | 131 | const toDateTime = timezone 132 | ? DateTime.fromISO(event.startDate.toString(), { zone: timezone }) 133 | : DateTime.fromMillis(event.endDate.toUnixTime() * 1000); 134 | 135 | markwhenText += `${dateRangeToString( 136 | { 137 | fromDateTime, 138 | toDateTime, 139 | }, 140 | "day", 141 | undefined 142 | )}: ${event.summary}\n`; 143 | if (event.description) { 144 | const adjustedDescription = event.description 145 | .split("\n") 146 | .filter((line) => !line.startsWith("-::~:~")) 147 | .join("\n"); 148 | markwhenText += `${adjustedDescription}\n`; 149 | } 150 | } 151 | const fileName = 152 | inputFileName.substring(0, inputFileName.lastIndexOf(".")) + ".mw"; 153 | writeFileSync(fileName, markwhenText); 154 | return; 155 | } 156 | const { parsed, rawText } = getParseFromFile(inputFileName); 157 | 158 | const desintationArgsIndex = serving ? 2 : 1; 159 | if (args.destination && args._[desintationArgsIndex]) { 160 | er( 161 | `Ambiguous output - ${args.destination} & ${args._[desintationArgsIndex]}` 162 | ); 163 | return; 164 | } 165 | 166 | let destination: string | undefined; 167 | if (args.destination) { 168 | destination = args.destination; 169 | } else if (args._[desintationArgsIndex]) { 170 | destination = `${args._[desintationArgsIndex]}`; 171 | } 172 | 173 | let outputType = args.outputType as ViewType | undefined; 174 | if (!args.outputType) { 175 | // Try to infer output type from filename 176 | const options = [ 177 | [".json", "json"], 178 | ["timeline.html", "timeline"], 179 | ["calendar.html", "calendar"], 180 | ["resume.html", "resume"], 181 | ] as [string, typeof outputType][]; 182 | 183 | for (const option of options) { 184 | if (destination?.endsWith(option[0])) { 185 | outputType = option[1]; 186 | } 187 | } 188 | } 189 | 190 | if (serving) { 191 | if (outputType === "json") { 192 | console.log( 193 | "Specify a view to serve with --output: `mw serve file.mw --output timeline`" 194 | ); 195 | return; 196 | } 197 | const wsPort = 198 | parseInt(process.env.SOCKET_PORT || "0") || args.socketPort || 3001; 199 | const wss = new WebSocketServer({ port: wsPort }); 200 | wss.on("connection", (ws) => { 201 | watch(path.join("" + inputFileName), "utf-8", (type, f) => { 202 | console.log("Updating..."); 203 | const { parsed, rawText } = getParseFromFile(inputFileName); 204 | ws.send( 205 | JSON.stringify({ 206 | type: "state", 207 | request: true, 208 | id: `markwhen_1234`, 209 | params: appState(parsed, rawText), 210 | }) 211 | ); 212 | }); 213 | }); 214 | 215 | const app = express(); 216 | app.get("/", (req, res) => { 217 | if (!outputType) { 218 | const headerPreferredView = parsed.timelines[0].header?.preferredView; 219 | if ( 220 | headerPreferredView && 221 | ["timeline", "resume", "calendar"].includes(headerPreferredView) 222 | ) { 223 | outputType = headerPreferredView as Exclude; 224 | } else { 225 | outputType = "timeline"; 226 | } 227 | } 228 | const html = injectScript( 229 | templateHtml(outputType as Exclude), 230 | `var __markwhen_wss_url = "ws://localhost:${wsPort}"; 231 | var __markwhen_initial_state = ${JSON.stringify(appState(parsed, rawText))}` 232 | ); 233 | res.status(200).send(html); 234 | }); 235 | 236 | const port = process.env.PORT || args.port || 3000; 237 | app.listen(port); 238 | console.log(`Server running at http://localhost:${port}`); 239 | } else if (outputType === "json") { 240 | const asJson = JSON.stringify(parsed); 241 | writeFileSync(destination || "timeline.mw.json", asJson); 242 | return; 243 | } else { 244 | if (!outputType) { 245 | const headerPreferredView = parsed.timelines[0].header?.preferredView; 246 | if ( 247 | headerPreferredView && 248 | ["timeline", "resume", "calendar"].includes(headerPreferredView) 249 | ) { 250 | outputType = headerPreferredView as Exclude; 251 | } else { 252 | outputType = "timeline"; 253 | } 254 | } 255 | const initialHtml = getInitialHtml(parsed, rawText, outputType); 256 | writeFileSync(destination || `${outputType}.html`, initialHtml); 257 | } 258 | } 259 | 260 | main(); 261 | -------------------------------------------------------------------------------- /test/test.mw: -------------------------------------------------------------------------------- 1 | title: Welcome to Markwhen 2 | 3 | #Project1: #d336b1 4 | #welcome: orange 5 | 6 | group new group up here 7 | January 6 2021: shit be happening yo 8 | 9 | endGroup 10 | section Welcome #welcome 11 | now: This example timeline showcases some of markwhen's features. 12 | 13 | now: For more information, view the documentation [here](https://docs.markwhen.com) or join the [discord](https://discord.gg/kQbqP4uz) 14 | #welcome 15 | 16 | now: Note that changes you make here are not saved 17 | If you want to make a new markwhen you should open a tab at the bottom or click open in the sidebar 18 | endSection 19 | 20 | section All Projects 21 | group Project 1 #Project1 22 | // Supports ISO8601 23 | 2023-01/2023-03: Sub task #John 24 | 2023-03/2023-06: Sub task 2 #Michelle 25 | More info about sub task 2 26 | 27 | - list item only 28 | - another item in the list 29 | - [] checkbox thing 30 | - [ ] We need to get this done 31 | - [x] And this 32 | - [ ] This one is extra 33 | 34 | 2023-07: Yearly planning 35 | endGroup 36 | group Project 2 #Project2 37 | 2023-04/4 months: Larger sub task #Danielle 38 | 39 | // Supports American date formats 40 | 03/2023 - 1 year: Longer ongoing task #Michelle 41 | 42 | - [x] Sub task 1 43 | - [x] Sub task 2 44 | - [ ] Sub task 3 45 | - [ ] Sub task 4 46 | - [ ] so many checkboxes omg 47 | 48 | 10/2023 - 2 months: Holiday season 49 | endGroup 50 | 51 | group Project 5 52 | 01/2024: Project kickoff 53 | 02/2024-04/2024: Other stuff 54 | endGroup 55 | endSection 56 | 57 | 2023-01-03 every other week for 1 year: Biweekly meeting 58 | 59 | // Events that don't have explicit end dates have inferred ranges - for example, when a year is specified, it lasts from the beginning of that year to the end of it. 60 | 2024: A year-long event 61 | 62 | // Inferred ranges are as granular as their definitions. 63 | 09/2024: one month 64 | 65 | 2025-05-05: one day 66 | 67 | Jan 4 2025 8am: instant 68 | 69 | // You can also be specific with your ranges 70 | 2024/2025: An event that lasts two years 71 | 72 | November 8, 2022 9am - November 9, 2023, 10am: one year, one day, and one hour 73 | 74 | now: [More documentation](https://docs.markwhen.com/syntax/events.html) 75 | 76 | // Event descriptions last from the date range definition up to the next event 77 | 2029-04-25/2029-05-03: Descriptions can be one line 78 | 79 | 2029-04-25/2029-05-03: Or 80 | they can span 81 | multiple lines 82 | 83 | 1/27/2025: [] An event can have a checkbox for completion 84 | Put square brackets at the start of the event description 85 | 86 | 1/27/2026: [x] To mark an event as completed, put an x in the square brackets 87 | 88 | 1/27/2027: Events can have lists 89 | 90 | - [ ] checkbox list item 91 | - [x] a completed checkbox list item 92 | - simple list item 93 | - another simple list item 94 | 95 | 1/27/2028 - 1 year: 68% Manually indicate an event's completion with a percentage in the description 96 | 97 | Partially completed events will have their event bar partially filled that amount 98 | 99 | 1 year: Links are markdown-style: [This is a link](https://markwhen.com) 100 | 101 | 1 year: Images are also markdown-style: 102 | ![](https://blog.markwhen.com/images/calendar1.png) 103 | 104 | 1 year: Locations (which are more useful for the map view) can be indicated in a similar way: [Hawaii](location) [Alaska](map) 105 | 106 | 2024: Refer to other markwhen documents with `@` syntax: @rob 107 | 108 | now: [More documentation](https://docs.markwhen.com/syntax/event-descriptions.html) 109 | 110 | // Events can be grouped together 111 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "module": "ES2020", 5 | "moduleResolution": "Node", 6 | "lib": ["ESNext", "ESNext.AsyncIterable", "DOM"], 7 | "esModuleInterop": true, 8 | "allowJs": true, 9 | "sourceMap": true, 10 | "strict": true, 11 | "experimentalDecorators": true, 12 | "baseUrl": ".", 13 | "paths": { 14 | "~/*": ["./*"], 15 | "@/*": ["./*"] 16 | }, 17 | "types": ["@types/node"], 18 | "outDir": "lib", 19 | "skipLibCheck": true 20 | }, 21 | "include": ["src/**/*"] 22 | } 23 | --------------------------------------------------------------------------------