├── .editorconfig ├── .eslint.config.js ├── .github ├── FUNDING.yml ├── example.gif └── workflows │ └── node.js.yml ├── .gitignore ├── .prettierignore ├── .prettierrc.json ├── LICENSE ├── MMM-ModuleScheduler.js ├── README.md ├── node_helper.js ├── package-lock.json ├── package.json └── tests └── node_helper.test.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 2 8 | indent_style = space 9 | insert_final_newline = true 10 | max_line_length = 250 11 | trim_trailing_whitespace = true 12 | 13 | [*.{js,json}] 14 | indent_size = 4 15 | indent_style = tab 16 | -------------------------------------------------------------------------------- /.eslint.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "eslint/config"; 2 | import eslintPluginPrettier from "eslint-plugin-prettier"; 3 | import eslintPluginJsdoc from "eslint-plugin-jsdoc"; 4 | import globals from "globals"; 5 | import path from "node:path"; 6 | import { fileURLToPath } from "node:url"; 7 | import js from "@eslint/js"; 8 | import { FlatCompat } from "@eslint/eslintrc"; 9 | 10 | const __filename = fileURLToPath(import.meta.url); 11 | const __dirname = path.dirname(__filename); 12 | const compat = new FlatCompat({ 13 | baseDirectory: __dirname, 14 | recommendedConfig: js.configs.recommended, 15 | allConfig: js.configs.all 16 | }); 17 | 18 | export default defineConfig([ 19 | { 20 | extends: compat.extends("eslint:recommended", "plugin:prettier/recommended", "plugin:jsdoc/recommended"), 21 | 22 | plugins: { 23 | eslintPluginPrettier, 24 | eslintPluginJsdoc 25 | }, 26 | 27 | languageOptions: { 28 | globals: { 29 | ...globals.browser, 30 | ...globals.mocha, 31 | ...globals.node, 32 | config: true, 33 | Log: true, 34 | MM: true, 35 | Module: true, 36 | moment: true 37 | }, 38 | 39 | ecmaVersion: 2017, 40 | sourceType: "module", 41 | 42 | parserOptions: { 43 | ecmaFeatures: { 44 | globalReturn: true 45 | } 46 | } 47 | }, 48 | 49 | rules: { 50 | "prettier/prettier": "error", 51 | eqeqeq: "error", 52 | "no-prototype-builtins": "off", 53 | "no-unused-vars": "off" 54 | } 55 | } 56 | ]); 57 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: ianperrin 2 | custom: ["https://paypal.me/ianperrin01"] 3 | -------------------------------------------------------------------------------- /.github/example.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ianperrin/MMM-ModuleScheduler/adbef27b28548591061fff8328c58d6d025a5a9f/.github/example.gif -------------------------------------------------------------------------------- /.github/workflows/node.js.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: Tests 5 | 6 | on: 7 | push: 8 | branches: [master, develop] 9 | pull_request: 10 | branches: [master, develop] 11 | 12 | jobs: 13 | test: 14 | runs-on: ubuntu-latest 15 | 16 | strategy: 17 | matrix: 18 | node-version: [22.x] 19 | 20 | steps: 21 | - name: Checkout MagicMirror repo 22 | uses: actions/checkout@v2 23 | with: 24 | repository: MichMich/MagicMirror 25 | path: MagicMirror 26 | 27 | - name: Checkout Module repo 28 | uses: actions/checkout@v2 29 | with: 30 | path: MagicMirror/modules/MMM-ModuleScheduler 31 | 32 | - name: Use Node.js ${{ matrix.node-version }} 33 | uses: actions/setup-node@v2 34 | with: 35 | node-version: ${{ matrix.node-version }} 36 | 37 | - name: Install MagicMirror 38 | run: | 39 | cd MagicMirror 40 | Xvfb :99 -screen 0 1024x768x16 & 41 | export DISPLAY=:99 42 | npm ci 43 | 44 | - name: Run tests 45 | run: | 46 | cd MagicMirror/modules/MMM-ModuleScheduler 47 | npm ci 48 | npm run test 49 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # nyc test coverage 18 | .nyc_output 19 | 20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 21 | .grunt 22 | 23 | # node-waf configuration 24 | .lock-wscript 25 | 26 | # Compiled binary addons (http://nodejs.org/api/addons.html) 27 | build/Release 28 | 29 | # Dependency directories 30 | node_modules 31 | jspm_packages 32 | 33 | # Optional npm cache directory 34 | .npm 35 | 36 | # Optional REPL history 37 | .node_repl_history 38 | 39 | # Various Windows ignoramuses. 40 | Thumbs.db 41 | ehthumbs.db 42 | Desktop.ini 43 | $RECYCLE.BIN/ 44 | *.cab 45 | *.msi 46 | *.msm 47 | *.msp 48 | *.lnk 49 | 50 | # Various OSX ignoramuses. 51 | .DS_Store 52 | .AppleDouble 53 | .LSOverride 54 | Icon 55 | ._* 56 | .DocumentRevisions-V100 57 | .fseventsd 58 | .Spotlight-V100 59 | .TemporaryItems 60 | .Trashes 61 | .VolumeIcon.icns 62 | .AppleDB 63 | .AppleDesktop 64 | Network Trash Folder 65 | Temporary Items 66 | .apdisk 67 | 68 | # Various Linux ignoramuses. 69 | .fuse_hidden* 70 | .directory 71 | .Trash-* 72 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | package-lock.json -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "none" 3 | } 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Ian Perrin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /MMM-ModuleScheduler.js: -------------------------------------------------------------------------------- 1 | /* Magic Mirror 2 | * Module: MMM-ModuleScheduler 3 | * 4 | * By Ian Perrin http://ianperrin.com 5 | * MIT Licensed. 6 | */ 7 | Module.register("MMM-ModuleScheduler", { 8 | // Set the minimum MagicMirror module version for this module. 9 | requiresVersion: "2.0.0", 10 | 11 | // Module config defaults. 12 | defaults: { 13 | schedulerClass: "scheduler", 14 | animationSpeed: 1000, 15 | notification_schedule: false, 16 | global_schedule: false, 17 | debug: false, 18 | uselock: true 19 | }, 20 | 21 | // Define start sequence. 22 | start: function () { 23 | Log.info("Starting module: " + this.name); 24 | this.sendSocketNotification("INITIALISE_SCHEDULER", this.config); 25 | }, 26 | 27 | notificationReceived: function (notification, payload, sender) { 28 | var self = this; 29 | if (sender === undefined && notification === "ALL_MODULES_STARTED") { 30 | // Create notification schedules 31 | if (this.config.notification_schedule) { 32 | this.sendSocketNotification("CREATE_NOTIFICATION_SCHEDULE", this.config.notification_schedule); 33 | } 34 | return; 35 | } 36 | if (sender === undefined && notification === "DOM_OBJECTS_CREATED") { 37 | // Create global schedules 38 | if (typeof this.config.global_schedule === "object") { 39 | this.sendSocketNotification("CREATE_GLOBAL_SCHEDULE", this.config.global_schedule); 40 | } 41 | // Create module schedules 42 | MM.getModules() 43 | .exceptModule(this) 44 | .withClass(this.config.schedulerClass) 45 | .enumerate(function (module) { 46 | Log.log(self.name + " wants to schedule the display of " + module.name); 47 | if (typeof module.config.module_schedule === "object") { 48 | self.sendSocketNotification("CREATE_MODULE_SCHEDULE", { name: module.name, id: module.identifier, schedule: module.config.module_schedule }); 49 | } else { 50 | Log.error(module.name + " is configured to be scheduled, but the module_schedule option is undefined"); 51 | } 52 | }); 53 | return; 54 | } 55 | }, 56 | 57 | socketNotificationReceived: function (notification, payload) { 58 | var self = this; 59 | if (notification === "SHOW_MODULE" || notification === "HIDE_MODULE" || notification === "DIM_MODULE") { 60 | Log.log(this.name + " received a " + notification + " notification for " + payload.target); 61 | MM.getModules() 62 | .exceptModule(this) 63 | .withClass(this.config.schedulerClass) 64 | .enumerate(function (module) { 65 | if (payload.target === module.identifier) { 66 | self.setModuleDisplay(module, notification, payload.dimLevel ? payload.dimLevel : "25"); 67 | return; 68 | } 69 | }); 70 | } 71 | if (notification === "SHOW_MODULES" || notification === "HIDE_MODULES" || notification === "DIM_MODULES") { 72 | Log.log(this.name + " received a " + notification + " notification for " + (payload.target ? payload.target : "all") + " modules"); 73 | // Get all modules except this one 74 | var modules = MM.getModules().exceptModule(this); 75 | // Restrict to group of modules with specified class 76 | if (payload.target) { 77 | modules = modules.withClass(payload.target); 78 | } 79 | // Ignore specified modules 80 | if (payload.ignoreModules) { 81 | modules = modules.filter(function (module) { 82 | if (payload.ignoreModules.indexOf(module.name) === -1) { 83 | return true; 84 | } 85 | Log.log(self.name + " is ignoring " + module.name + " from the " + notification + " notification for " + (payload.target ? payload.target : "all") + " modules"); 86 | return false; 87 | }); 88 | } 89 | // Process the notification request 90 | var action = notification.replace("_MODULES", "_MODULE"); 91 | var brightness = payload.dimLevel ? payload.dimLevel : "25"; 92 | for (var i = 0; i < modules.length; i++) { 93 | this.setModuleDisplay(modules[i], action, brightness); 94 | } 95 | return; 96 | } 97 | if (notification === "SEND_NOTIFICATION") { 98 | Log.log(this.name + " received a request to send a " + payload.target + " notification"); 99 | this.sendNotification(payload.target, payload.payload); 100 | return; 101 | } 102 | }, 103 | 104 | setModuleDisplay: function (module, action, brightness) { 105 | const options = this.config.uselock ? { lockString: this.identifier } : ""; 106 | Log.log(this.name + " is processing the " + action + (action === "DIM_MODULE" ? " (" + brightness + "%)" : "") + " request for " + module.identifier); 107 | 108 | if (action === "SHOW_MODULE") { 109 | module["show"]( 110 | this.config.animationSpeed, 111 | () => { 112 | Log.log(this.name + " has shown " + module.identifier); 113 | this.setModuleBrightness(module.identifier, 100); 114 | }, 115 | options 116 | ); 117 | return true; 118 | } 119 | 120 | if (action === "HIDE_MODULE") { 121 | module.hide(this.config.animationSpeed, Log.log(this.name + " has hidden " + module.identifier), options); 122 | return true; 123 | } 124 | 125 | if (action === "DIM_MODULE") { 126 | this.setModuleBrightness(module.identifier, brightness); 127 | return true; 128 | } 129 | 130 | return false; 131 | }, 132 | setModuleBrightness(moduleIdentifier, brightness = 100) { 133 | const moduleDiv = document.getElementById(moduleIdentifier); 134 | if (moduleDiv) { 135 | moduleDiv.style.filter = "brightness(" + brightness + "%)"; 136 | Log.log(this.name + " has set the brightness of " + moduleIdentifier + " to " + brightness + "%"); 137 | } 138 | } 139 | }); 140 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MMM-ModuleScheduler 2 | 3 | A [MagicMirror²](https://magicmirror.builders) helper module to schedule when modules should be shown, hidden or dimmed and when notifications should be sent. 4 | 5 | [![Platform](https://img.shields.io/badge/platform-MagicMirror-informational)](https://MagicMirror.builders) 6 | [![license](https://img.shields.io/github/license/mashape/apistatus.svg)](https://raw.githubusercontent.com/ianperrin/MMM-ModuleScheduler/master/LICENSE) 7 | ![Test Status](https://github.com/ianperrin/MMM-ModuleScheduler/actions/workflows/node.js.yml/badge.svg) 8 | [![Known Vulnerabilities](https://snyk.io/test/github/ianperrin/MMM-ModuleScheduler/badge.svg)](https://snyk.io/test/github/ianperrin/MMM-ModuleScheduler) 9 | 10 | ![Example Scheduling](.github/example.gif) 11 | 12 | ## Installation 13 | 14 | In your terminal, go to your MagicMirror's Module folder, clone this repository, go to the modules folder, install the dependencies: 15 | 16 | ``` 17 | cd ~/MagicMirror/modules 18 | git clone https://github.com/ianperrin/MMM-ModuleScheduler.git 19 | cd MMM-ModuleScheduler 20 | npm install --omit=dev 21 | ``` 22 | 23 | Add the module to the modules array in the `config/config.js` file: 24 | 25 | ```javascript 26 | { 27 | module: 'MMM-ModuleScheduler' 28 | }, 29 | ``` 30 | 31 | ## Config Options 32 | 33 | | **Option** | **Default** | **Description** | 34 | | ----------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | 35 | | `schedulerClass` | 'scheduler' | **Optional** The name of the class which should be used to identify the modules which have an individual schedule. | 36 | | `animationSpeed` | 1000 | **Optional** The speed of the show and hide animations in milliseconds | 37 | | `notification_schedule` | | **Optional** A single, or array of multiple definitions to schedule when notifications should be sent. See [Scheduling Notifications](#scheduling-notifications) | 38 | | `global_schedule` | | **Optional** A single, or array of multiple definitions to schedule when all modules should be shown/hidden/dimmed. See [Global Schedules](#global-schedules) | 39 | | `uselock` | `true` | **Optional** If set to `false`, scheduler don't lock the hidden modules. Other modules can then be used to show the modules if they are hidden by the scheduler. | 40 | | `debug` | `true` | **Optional** Outputs messages to the console/log when set to `true` | 41 | 42 | ## Config Examples 43 | 44 | Sending notifications 45 | 46 | - [Basic example](#scheduling-notifications) 47 | - [Multiple notifications](#scheduling-multiple-notifications) 48 | - [Remote control notifications](#scheduling-actions-to-control-your-magicmirror-pi-and-monitorscreen) 49 | 50 | Module Display 51 | 52 | - [Hide or show all modules](#global-schedules) 53 | - [Hide or show a group of modules](#group-schedules) 54 | - [Hide or show individual modules](#individual-module-schedules) 55 | - [Dimming modules](#dimming-modules) 56 | - [Multiple schedules](#multiple-schedules) 57 | - [Ignoring Modules](#ignoring-modules) 58 | 59 | ### Scheduling Notifications 60 | 61 | To schedule the sending of a notification to other modules, add a `notification_schedule` definition to the MMM-ModuleScheduler config, e.g. 62 | 63 | ```javascript 64 | { 65 | module: 'MMM-ModuleScheduler', 66 | config: { 67 | // SHOW AN ALERT AT 09:30 EVERY DAY (see https://github.com/MichMich/MagicMirror/tree/develop/modules/default/alert) 68 | notification_schedule: { 69 | notification: 'SHOW_ALERT', 70 | schedule: '30 9 * * *', 71 | payload: { 72 | type: "notification", 73 | title: 'Scheduled alert!' 74 | } 75 | } 76 | } 77 | }, 78 | ``` 79 | 80 | **Notes** 81 | 82 | - `notification` is required and should be the identifier of the notification to be sent to all other modules. 83 | - `schedule` is required and determines when the notification will be sent. It should be a valid cron expression - see [crontab.guru](http://crontab.guru/). 84 | - `payload` is optional and its contents will be determined by the module receiving the notification. 85 | 86 | * When specifying your schedule values make sure that your values fall within the ranges below. 87 | 88 | | **Unit** | **Format** | 89 | | -------------- | -------------- | 90 | | `Seconds` | 0-59 | 91 | | `Minutes` | 0-59 | 92 | | `Hours` | 0-23 | 93 | | `Day of Month` | 1-31 | 94 | | `Months` | 0-11 (Jan-Dec) | 95 | | `Day of Week` | 0-6 (Sun-Sat) | 96 | 97 | #### Scheduling Multiple Notifications 98 | 99 | Multiple `notification_schedule` definitions can be added using an array, e.g. 100 | 101 | ```javascript 102 | { 103 | module: 'MMM-ModuleScheduler', 104 | config: { 105 | notification_schedule: [ 106 | // SHOW AN ALERT AT 07:30 EVERY DAY 107 | {notification: 'SHOW_ALERT', schedule: '30 7 * * *', payload: {type: "notification", title: 'Good morning!'}}, 108 | // SHOW AN ALERT AT 17:45 EVERY DAY 109 | {notification: 'SHOW_ALERT', schedule: '17 45 * * *', payload: {type: "notification", title: 'Good afternoon!'}} 110 | ] 111 | } 112 | } 113 | ``` 114 | 115 | #### Scheduling actions to control your MagicMirror, Pi and monitor/screen 116 | 117 | Used in conjunction with [MMM-Remote-Control](https://github.com/Jopyth/MMM-Remote-Control) module, the `notification_schedule` definitions can create schedules to control your MagicMirror, Pi and monitor/screen, e.g. 118 | 119 | ```javascript 120 | { 121 | module: 'MMM-ModuleScheduler', 122 | config: { 123 | notification_schedule: [ 124 | // TURN THE MONITOR/SCREEN ON AT 07:30 EVERY DAY 125 | {notification: 'REMOTE_ACTION', schedule: '30 7 * * *', payload: {action: "MONITORON"}}, 126 | // TURN THE MONITOR/SCREEN OFF AT 22:30 EVERY DAY 127 | {notification: 'REMOTE_ACTION', schedule: '30 22 * * *', payload: {action: "MONITOROFF"}}, 128 | // RESTART THE MAGICMIRROR PROCESS AT 2am EVERY SUNDAY 129 | {notification: 'REMOTE_ACTION', schedule: '0 2 * * SUN', payload: {action: "RESTART"}} 130 | ] 131 | } 132 | }, 133 | ``` 134 | 135 | **Notes** 136 | 137 | - A full list of remote actions available for controlling your MagicMirror, Pi and monitor/screen are available in the [MMM-Remote-Control module documentation](https://github.com/Jopyth/MMM-Remote-Control#list-of-actions) 138 | - If you simply want to hide and show modules, it is recommended to use the module display scheduling options defined below, rather than the `SHOW` and `HIDE` remote actions. 139 | 140 | ### Scheduling Module Display 141 | 142 | #### Global Schedules 143 | 144 | To schedule when all modules are shown (or hidden) by the Magic Mirror, add a `global_schedule` definition to the MMM-ModuleScheduler config, e.g. 145 | 146 | ```javascript 147 | { 148 | module: 'MMM-ModuleScheduler', 149 | config: { 150 | // SHOW ALL MODULES AT 06:00 AND HIDE AT 22:00 EVERY DAY 151 | global_schedule: {from: '0 6 * * *', to: '0 22 * * *' }, 152 | } 153 | }, 154 | ``` 155 | 156 | #### Group Schedules 157 | 158 | To apply a schedule to a group of modules, add the `groupClass` option to the `global_schedule` definition, e.g. 159 | 160 | ```javascript 161 | { 162 | module: 'MMM-ModuleScheduler', 163 | config: { 164 | // SHOW MODULES WITH THE CLASS 'daytime_scheduler' AT 06:00 AND HIDE AT 22:00 EVERY DAY 165 | global_schedule: {from: '0 6 * * *', to: '0 22 * * *', groupClass: 'daytime_scheduler'}, 166 | } 167 | }, 168 | { 169 | module: 'clock', 170 | position: 'top_left', 171 | classes: 'daytime_scheduler' 172 | } 173 | { 174 | module: 'compliments', 175 | position: 'lower_third', 176 | classes: 'daytime_scheduler' 177 | }, 178 | 179 | ``` 180 | 181 | **Notes** 182 | 183 | - Modules scheduled as a group, only need the `groupClass` adding to the `classes` option in their config. The `schedulerClass` option can be omitted unless indiviudal schedules also exist. 184 | 185 | #### Individual Module Schedules 186 | 187 | To schedule when an individual module is shown (or hidden) by the Magic Mirror, modify the configuration for that module so that it includes the `classes` and `module_schedule` options. e.g. 188 | 189 | ```javascript 190 | { 191 | module: 'calendar', 192 | header: 'US Holidays', 193 | position: 'top_left', 194 | classes: 'scheduler', 195 | config: { 196 | // DISPLAY THE CALENDAR BETWEEN 09:00 and 18:00 ON WEDNESDAYS 197 | module_schedule: {from: '0 9 * * 3', to: '0 18 * * 3' }, 198 | calendars: [ 199 | { 200 | symbol: 'calendar-check-o ', 201 | url: 'webcal://www.calendarlabs.com/templates/ical/US-Holidays.ics' 202 | } 203 | ] 204 | } 205 | }, 206 | ``` 207 | 208 | **Notes** 209 | 210 | - `from` is required and determines when the module will be shown. It should be a valid cron expression - see [crontab.guru](http://crontab.guru/). 211 | - `to` is required and determines when the module will be hidden. It should be a valid cron expression - see [crontab.guru](http://crontab.guru/). 212 | 213 | #### Dimming Modules 214 | 215 | To dim modules, rather than hide them, add the `dimLevel` option (as a percentage between 0 and 100) to the `global_schedule` and `module_schedule` definitions. e.g. 216 | 217 | ```javascript 218 | { 219 | module: 'MMM-ModuleScheduler', 220 | config: { 221 | // SHOW ALL MODULES AT 06:00 AND DIM THEM TO 40% AT 22:00 222 | global_schedule: {from: '0 6 * * *', to: '0 22 * * *', dimLevel: '40' }, 223 | } 224 | }, 225 | { 226 | module: 'clock', 227 | position: 'top_left', 228 | classes: 'scheduler', 229 | config: { 230 | // SHOW THE CLOCK AT 06:30 AND DIM IT TO 25% AT 22:30 231 | module_schedule: {from: '30 6 * * *', to: '30 22 * * *', dimLevel: '25'} 232 | } 233 | }, 234 | ``` 235 | 236 | **Note:** 237 | 238 | - The modules will be shown (full brightness) based on the `from` expression 239 | - The modules will then either be dimmed (if the `dimLevel` option is set) based on the `to` expression. 240 | - Take care when adding both `global_schedule` and `module_schedule` definitions as MMM-ModuleScheduler performs no validation that they will be compatible. 241 | 242 | #### Multiple Schedules 243 | 244 | For more complex scheduling, multiple `global_schedule` and `module_schedule` definitions can be added using an array, e.g. 245 | 246 | ```javascript 247 | { 248 | module: 'MMM-ModuleScheduler', 249 | config: { 250 | global_schedule: [ 251 | // SHOW MODULES WITH THE CLASS 'morning_scheduler' AT 06:00 AND HIDE AT 09:00 EVERY DAY 252 | {from: '0 6 * * *', to: '0 9 * * *', groupClass: 'morning_scheduler'}, 253 | // SHOW MODULES WITH THE CLASS 'evening_scheduler' AT 17:00 AND HIDE AT 23:00 EVERY DAY 254 | {from: '0 17 * * *', to: '0 22 * * *', groupClass: 'evening_scheduler'}, 255 | ] 256 | } 257 | }, 258 | { 259 | module: 'clock', 260 | position: 'top_left', 261 | classes: 'scheduler', 262 | config: { 263 | // DISPLAY BETWEEN 09:30 ON SATURDAYS AND 22:30 ON SUNDAYS, 264 | // THEN AGAIN BETWEEN 20:00 AND 23:00 ON TUESDAYS AND WEDNESDAYS 265 | module_schedule: [ 266 | {from: '30 9 * * SAT', to: '30 22 * * SUN'}, 267 | {from: '0 20 * * 2-3', to: '0 23 * * 2-3'} 268 | ] 269 | } 270 | }, 271 | ``` 272 | 273 | **Note:** 274 | 275 | - Take care when adding both `global_schedule` and `module_schedule` definitions as MMM-ModuleScheduler performs no validation that they will be compatible. 276 | 277 | #### Ignoring Modules 278 | 279 | To ignore modules from being shown, hidden or dimmed by a global schedules, add the `ignoreModules` option to the `global_schedule` definition e.g. 280 | 281 | ```javascript 282 | { 283 | module: 'MMM-ModuleScheduler', 284 | config: { 285 | // SHOW ALL MODULES EXCEPT clock AND calender BETWEEN 06:00 AND 22:00 286 | global_schedule: {from: '0 6 * * *', to: '0 22 * * *', ignoreModules: ['clock', 'calendar'] }, 287 | } 288 | }, 289 | ``` 290 | 291 | **Note:** 292 | 293 | - Modules are ignored based on their name, as defined in the config file. If multiple instances of a single module are defined in the `config.js` file, all instances will be ignored using this option. 294 | 295 | ## Updating 296 | 297 | To update the module to the latest version, use your terminal to go to your MMM-ModuleScheduler module folder and type the following command: 298 | 299 | ``` 300 | git pull 301 | ``` 302 | 303 | If you haven't changed the modules, this should work without any problems. 304 | Type `git status` to see your changes, if there are any, you can reset them with `git reset --hard`. After that, git pull should be possible. 305 | -------------------------------------------------------------------------------- /node_helper.js: -------------------------------------------------------------------------------- 1 | /* Magic Mirror 2 | * Node Helper: MMM-ModuleScheduler 3 | * 4 | * By Ian Perrin http://ianperrin.com 5 | * MIT Licensed. 6 | */ 7 | 8 | var NodeHelper = require("node_helper"); 9 | var CronJob = require("cron").CronJob; 10 | 11 | // MODULE CONSTANTS 12 | const SCHEDULE_TYPE_GLOBAL = "global"; 13 | const SCHEDULE_TYPE_GROUP = "group"; 14 | const SCHEDULE_TYPE_MODULE = "module"; 15 | const SCHEDULE_TYPE_NOTIFICATION = "notification"; 16 | const JOB_ACTION_SHOW = "show"; 17 | const JOB_ACTION_HIDE = "hide"; 18 | const JOB_ACTION_DIM = "dim"; 19 | const JOB_ACTION_SEND = "send"; 20 | 21 | module.exports = NodeHelper.create({ 22 | scheduledJobs: [], 23 | 24 | // Override start method. 25 | start: function () { 26 | console.log("Starting node helper for: " + this.name); 27 | }, 28 | 29 | // Override socketNotificationReceived method. 30 | socketNotificationReceived: function (notification, payload) { 31 | this.log(this.name + " received " + notification); 32 | 33 | if (notification === "INITIALISE_SCHEDULER") { 34 | this.log(this.name + " is setting the config"); 35 | this.config = payload; 36 | this.removeScheduledJobs(); 37 | return true; 38 | } 39 | if (notification === "CREATE_NOTIFICATION_SCHEDULE") { 40 | this.createScheduleForNotifications(payload); 41 | return true; 42 | } 43 | if (notification === "CREATE_GLOBAL_SCHEDULE") { 44 | this.createGlobalSchedules(payload); 45 | return true; 46 | } 47 | if (notification === "CREATE_MODULE_SCHEDULE") { 48 | this.createScheduleForModule(payload); 49 | return true; 50 | } 51 | }, 52 | 53 | removeScheduledJobs: function () { 54 | this.log(this.name + " is removing all scheduled jobs"); 55 | for (var i = 0; i < this.scheduledJobs.length; i++) { 56 | var scheduledJob = this.scheduledJobs[i]; 57 | if (typeof scheduledJob.showJob === "object") { 58 | this.stopCronJob(scheduledJob.showJob); 59 | } 60 | if (typeof scheduledJob.hideJob === "object") { 61 | this.stopCronJob(scheduledJob.hideJob); 62 | } 63 | if (typeof scheduledJob.notificationJob === "object") { 64 | this.stopCronJob(scheduledJob.notificationJob); 65 | } 66 | } 67 | this.scheduledJobs.length = 0; 68 | }, 69 | 70 | stopCronJob: function (cronJob) { 71 | try { 72 | cronJob.stop(); 73 | } catch (ex) { 74 | this.log(this.name + " could not stop cronJob"); 75 | } 76 | }, 77 | 78 | createScheduleForNotifications: function (notification_schedule) { 79 | var notificationSchedules = this.getOrMakeArray(notification_schedule); 80 | 81 | for (var i = 0; i < notificationSchedules.length; i++) { 82 | var notificationSchedule = notificationSchedules[i]; 83 | 84 | // Validate Schedule Definition 85 | if (!this.isValidSchedule(notificationSchedule, SCHEDULE_TYPE_NOTIFICATION)) { 86 | break; 87 | } 88 | 89 | // Create cronJobs 90 | this.log(this.name + " is scheduling " + notificationSchedule.notification + ' using "' + notificationSchedule.schedule); 91 | var notificationJob = this.createCronJob(SCHEDULE_TYPE_NOTIFICATION, notificationSchedule.schedule, JOB_ACTION_SEND, { target: notificationSchedule.notification, payload: notificationSchedule.payload }); 92 | if (!notificationJob) { 93 | break; 94 | } 95 | 96 | // Store scheduledJobs 97 | this.scheduledJobs.push({ notificationJob: notificationJob }); 98 | 99 | this.log(this.name + " has scheduled " + notificationSchedule.notification); 100 | this.log(this.name + " will next send " + notificationSchedule.notification + " at " + new Date(notificationJob.nextDate())); 101 | } 102 | }, 103 | 104 | createScheduleForModule: function (module) { 105 | var moduleSchedules = this.getOrMakeArray(module.schedule); 106 | var nextShowDate, nextHideDate, nextDimLevel; 107 | 108 | for (var i = 0; i < moduleSchedules.length; i++) { 109 | var moduleSchedule = moduleSchedules[i]; 110 | 111 | // Validate Schedule Definition 112 | if (!this.isValidSchedule(moduleSchedule, SCHEDULE_TYPE_MODULE)) { 113 | break; 114 | } 115 | 116 | // Create cronJobs 117 | this.log(this.name + " is scheduling " + module.name + ' using "' + moduleSchedule.from + '" and "' + moduleSchedule.to + '" with dim level ' + moduleSchedule.dimLevel); 118 | var showJob = this.createCronJob(SCHEDULE_TYPE_MODULE, moduleSchedule.from, JOB_ACTION_SHOW, { target: module.id }); 119 | 120 | if (!showJob) { 121 | break; 122 | } 123 | var hideJobAction = moduleSchedule.dimLevel ? JOB_ACTION_DIM : JOB_ACTION_HIDE; 124 | var hideJob = this.createCronJob(SCHEDULE_TYPE_MODULE, moduleSchedule.to, hideJobAction, { target: module.id, dimLevel: moduleSchedule.dimLevel }); 125 | if (!hideJob) { 126 | showJob.stop(); 127 | break; 128 | } 129 | 130 | // Store scheduledJobs 131 | this.scheduledJobs.push({ module: module, schedule: moduleSchedule, showJob: showJob, hideJob: hideJob }); 132 | 133 | // Store next dates 134 | if (i === 0 || new Date(showJob.nextDate()) < nextShowDate) { 135 | nextShowDate = new Date(showJob.nextDate()); 136 | } 137 | if (i === 0 || new Date(hideJob.nextDate()) < nextShowDate) { 138 | nextHideDate = new Date(hideJob.nextDate()); 139 | nextDimLevel = moduleSchedule.dimLevel; 140 | } 141 | } 142 | 143 | if (nextHideDate && nextShowDate) { 144 | var now = new Date(); 145 | if (nextShowDate > now && nextHideDate > nextShowDate) { 146 | if (nextDimLevel > 0) { 147 | this.log(this.name + " is dimming " + module.name); 148 | this.sendSocketNotification("DIM_MODULE", { target: module.id, dimLevel: nextDimLevel }); 149 | } else { 150 | this.log(this.name + " is hiding " + module.name); 151 | this.sendSocketNotification("HIDE_MODULE", { target: module.id }); 152 | } 153 | } 154 | this.log(this.name + " has scheduled " + module.name); 155 | this.log(this.name + " will next show " + module.name + " at " + nextShowDate); 156 | this.log(this.name + " will next " + (nextDimLevel ? JOB_ACTION_DIM : JOB_ACTION_HIDE) + " " + module.name + " at " + nextHideDate); 157 | } 158 | }, 159 | 160 | createGlobalSchedules: function (global_schedule) { 161 | var globalSchedules = this.getOrMakeArray(global_schedule); 162 | 163 | for (var i = 0; i < globalSchedules.length; i++) { 164 | var globalSchedule = globalSchedules[i]; 165 | var groupOrAll = globalSchedule.groupClass ? globalSchedule.groupClass : "all"; 166 | 167 | // Validate Schedule Definition 168 | if (!this.isValidSchedule(globalSchedule, SCHEDULE_TYPE_GLOBAL)) { 169 | break; 170 | } 171 | 172 | // Create cronJobs 173 | this.log(this.name + " is creating a global schedule for " + groupOrAll + ' modules using "' + globalSchedule.from + '" and "' + globalSchedule.to + '" with dim level ' + globalSchedule.dimLevel); 174 | var showJob = this.createCronJob(SCHEDULE_TYPE_GLOBAL, globalSchedule.from, JOB_ACTION_SHOW, { target: globalSchedule.groupClass, ignoreModules: globalSchedule.ignoreModules }); 175 | if (!showJob) { 176 | break; 177 | } 178 | var hideJobAction = globalSchedule.dimLevel ? JOB_ACTION_DIM : JOB_ACTION_HIDE; 179 | var hideJob = this.createCronJob(SCHEDULE_TYPE_GLOBAL, globalSchedule.to, hideJobAction, { dimLevel: globalSchedule.dimLevel, target: globalSchedule.groupClass, ignoreModules: globalSchedule.ignoreModules }); 180 | if (!hideJob) { 181 | showJob.stop(); 182 | break; 183 | } 184 | 185 | // Store scheduledJobs 186 | this.scheduledJobs.push({ schedule: globalSchedule, showJob: showJob, hideJob: hideJob }); 187 | 188 | // Check next dates 189 | var nextShowDate = new Date(showJob.nextDate()); 190 | var nextHideDate = new Date(hideJob.nextDate()); 191 | var now = new Date(); 192 | if (nextShowDate > now && nextHideDate > nextShowDate) { 193 | if (globalSchedule.dimLevel > 0) { 194 | this.log(this.name + " is dimming " + groupOrAll + " modules"); 195 | this.sendSocketNotification("DIM_MODULES", { dimLevel: globalSchedule.dimLevel, target: globalSchedule.groupClass, ignoreModules: globalSchedule.ignoreModules }); 196 | } else { 197 | this.log(this.name + " is hiding " + groupOrAll + " modules"); 198 | this.sendSocketNotification("HIDE_MODULES", { target: globalSchedule.groupClass, ignoreModules: globalSchedule.ignoreModules }); 199 | } 200 | } 201 | this.log(this.name + " has created the global schedule for " + groupOrAll + " modules"); 202 | this.log(this.name + " will next show " + groupOrAll + " modules at " + nextShowDate); 203 | this.log(this.name + " will next " + (globalSchedule.dimLevel ? JOB_ACTION_DIM : JOB_ACTION_HIDE) + " " + groupOrAll + " modules at " + nextHideDate); 204 | } 205 | }, 206 | 207 | /** 208 | * Returns a CronJob object that has been scheduled to trigger the 209 | * specified action based on the supplied cronTime and options 210 | * @param {string} type the type of schedule to be created (either global, module or notification) 211 | * @param {object} cronTime a cron expression which determines when the job will fire 212 | * @param {string} action the action which should be performed (either show, hide, dim or send) 213 | * @param {object} options an object containing the options for the job (e.g. target, dimLevel, ignoreModules) 214 | * @returns {object} the scheduled cron job 215 | * @see CronJob 216 | */ 217 | createCronJob: function (type, cronTime, action, options) { 218 | var self = this; 219 | 220 | // Validate Action 221 | if (!this.isValidAction(action)) { 222 | return false; 223 | } 224 | 225 | // Build notification 226 | var notification = action.toUpperCase(); 227 | notification += type === SCHEDULE_TYPE_NOTIFICATION ? "_NOTIFICATION" : "_MODULE"; 228 | notification += type === SCHEDULE_TYPE_GLOBAL ? "S" : ""; 229 | 230 | try { 231 | var job = new CronJob( 232 | cronTime, 233 | function () { 234 | self.log(self.name + " is sending " + notification + " to " + options.target); 235 | self.sendSocketNotification(notification, options); 236 | self.log(self.name + " will next send " + notification + " to " + options.target + " at " + new Date(this.nextDate()) + ' based on "' + cronTime + '"'); 237 | }, 238 | function () { 239 | self.log(self.name + " has completed the " + action + " job for " + options.target + ' based on "' + cronTime + '"'); 240 | }, 241 | true 242 | ); 243 | return job; 244 | } catch (ex) { 245 | this.log(this.name + " could not create " + type + " schedule - check " + action + ' expression: "' + cronTime + '"'); 246 | return null; 247 | } 248 | }, 249 | 250 | /** 251 | * Returns either the original array or a new array holding the supplied value 252 | * @param {object} arrayOrString either an existing array or value to be used to create the new array 253 | * @returns {object} an array 254 | * @see Array 255 | */ 256 | getOrMakeArray: function (arrayOrString) { 257 | if (Array.isArray(arrayOrString)) { 258 | return arrayOrString; 259 | } else { 260 | return [arrayOrString]; 261 | } 262 | }, 263 | 264 | /** 265 | * Validates a schedule definition by determining whether it has the required 266 | * properties defined 267 | * @param {object} schedule_definition The schedule definition to be validated 268 | * @param {string} type The type of schedule to be created (either global, module or notification) 269 | * @returns {boolean} true or false 270 | */ 271 | isValidSchedule: function (schedule_definition, type) { 272 | var requiredProperties = this.getRequiredPropertiesForType(type); 273 | if (!requiredProperties) { 274 | this.log(this.name + " cannot validate required properties for `" + type + "_schedule`"); 275 | return false; 276 | } 277 | for (var i = 0; i < requiredProperties.length; i++) { 278 | var prop = requiredProperties[i]; 279 | if (!Object.prototype.hasOwnProperty.call(schedule_definition, prop)) { 280 | this.log(this.name + " cannot create schedule. Missing `" + prop + "` in `" + type + "_schedule`: " + JSON.stringify(schedule_definition)); 281 | return false; 282 | } 283 | } 284 | return true; 285 | }, 286 | 287 | /** 288 | * Determine whether a string is a valid action 289 | * @param {string} action The string to be validated 290 | * @returns {boolean} true or false 291 | */ 292 | isValidAction: function (action) { 293 | if (action !== JOB_ACTION_SHOW && action !== JOB_ACTION_HIDE && action !== JOB_ACTION_DIM && action !== JOB_ACTION_SEND) { 294 | this.log(this.name + " cannot create schedule. Expected show/hide/dim/send, not " + action); 295 | return false; 296 | } 297 | return true; 298 | }, 299 | 300 | /** 301 | * Gets an array of names for the properties required by the given schedule type 302 | * @param {string} type The scheduled type for which properties are required 303 | * @returns {object} An Array of property names 304 | */ 305 | getRequiredPropertiesForType: function (type) { 306 | if (type === SCHEDULE_TYPE_MODULE || type === SCHEDULE_TYPE_GLOBAL || type === SCHEDULE_TYPE_GROUP) { 307 | return ["from", "to"]; 308 | } else if (type === SCHEDULE_TYPE_NOTIFICATION) { 309 | return ["schedule", "notification"]; 310 | } else { 311 | return false; 312 | } 313 | }, 314 | 315 | /** 316 | * Outputs a message to the console/log when debugging is enabled 317 | * @param {string} msg A string containing the message to be output 318 | */ 319 | log: function (msg) { 320 | if (this.config && this.config.debug) { 321 | console.log(msg); 322 | } 323 | } 324 | }); 325 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "MMM-ModuleScheduler", 3 | "version": "1.5.1", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "MMM-ModuleScheduler", 9 | "version": "1.5.1", 10 | "license": "MIT", 11 | "dependencies": { 12 | "cron": "^4.3.0" 13 | }, 14 | "devDependencies": { 15 | "chai": "^5.2.0", 16 | "eslint": "^9.24.0", 17 | "eslint-config-prettier": "^10.1.2", 18 | "eslint-plugin-jsdoc": "^50.6.9", 19 | "eslint-plugin-prettier": "^5.2.6", 20 | "mocha": "^11.1.0", 21 | "module-alias": "^2.2.3", 22 | "prettier": "^3.5.3" 23 | } 24 | }, 25 | "node_modules/@es-joy/jsdoccomment": { 26 | "version": "0.49.0", 27 | "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.49.0.tgz", 28 | "integrity": "sha512-xjZTSFgECpb9Ohuk5yMX5RhUEbfeQcuOp8IF60e+wyzWEF0M5xeSgqsfLtvPEX8BIyOX9saZqzuGPmZ8oWc+5Q==", 29 | "dev": true, 30 | "license": "MIT", 31 | "dependencies": { 32 | "comment-parser": "1.4.1", 33 | "esquery": "^1.6.0", 34 | "jsdoc-type-pratt-parser": "~4.1.0" 35 | }, 36 | "engines": { 37 | "node": ">=16" 38 | } 39 | }, 40 | "node_modules/@eslint-community/eslint-utils": { 41 | "version": "4.6.1", 42 | "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.6.1.tgz", 43 | "integrity": "sha512-KTsJMmobmbrFLe3LDh0PC2FXpcSYJt/MLjlkh/9LEnmKYLSYmT/0EW9JWANjeoemiuZrmogti0tW5Ch+qNUYDw==", 44 | "dev": true, 45 | "license": "MIT", 46 | "dependencies": { 47 | "eslint-visitor-keys": "^3.4.3" 48 | }, 49 | "engines": { 50 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 51 | }, 52 | "funding": { 53 | "url": "https://opencollective.com/eslint" 54 | }, 55 | "peerDependencies": { 56 | "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" 57 | } 58 | }, 59 | "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { 60 | "version": "3.4.3", 61 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", 62 | "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", 63 | "dev": true, 64 | "license": "Apache-2.0", 65 | "engines": { 66 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 67 | }, 68 | "funding": { 69 | "url": "https://opencollective.com/eslint" 70 | } 71 | }, 72 | "node_modules/@eslint-community/regexpp": { 73 | "version": "4.12.1", 74 | "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", 75 | "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", 76 | "dev": true, 77 | "license": "MIT", 78 | "engines": { 79 | "node": "^12.0.0 || ^14.0.0 || >=16.0.0" 80 | } 81 | }, 82 | "node_modules/@eslint/config-array": { 83 | "version": "0.20.0", 84 | "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.0.tgz", 85 | "integrity": "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==", 86 | "dev": true, 87 | "license": "Apache-2.0", 88 | "dependencies": { 89 | "@eslint/object-schema": "^2.1.6", 90 | "debug": "^4.3.1", 91 | "minimatch": "^3.1.2" 92 | }, 93 | "engines": { 94 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 95 | } 96 | }, 97 | "node_modules/@eslint/config-helpers": { 98 | "version": "0.2.1", 99 | "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.1.tgz", 100 | "integrity": "sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==", 101 | "dev": true, 102 | "license": "Apache-2.0", 103 | "engines": { 104 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 105 | } 106 | }, 107 | "node_modules/@eslint/core": { 108 | "version": "0.12.0", 109 | "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz", 110 | "integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==", 111 | "dev": true, 112 | "license": "Apache-2.0", 113 | "dependencies": { 114 | "@types/json-schema": "^7.0.15" 115 | }, 116 | "engines": { 117 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 118 | } 119 | }, 120 | "node_modules/@eslint/eslintrc": { 121 | "version": "3.3.1", 122 | "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", 123 | "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", 124 | "dev": true, 125 | "license": "MIT", 126 | "dependencies": { 127 | "ajv": "^6.12.4", 128 | "debug": "^4.3.2", 129 | "espree": "^10.0.1", 130 | "globals": "^14.0.0", 131 | "ignore": "^5.2.0", 132 | "import-fresh": "^3.2.1", 133 | "js-yaml": "^4.1.0", 134 | "minimatch": "^3.1.2", 135 | "strip-json-comments": "^3.1.1" 136 | }, 137 | "engines": { 138 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 139 | }, 140 | "funding": { 141 | "url": "https://opencollective.com/eslint" 142 | } 143 | }, 144 | "node_modules/@eslint/js": { 145 | "version": "9.24.0", 146 | "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.24.0.tgz", 147 | "integrity": "sha512-uIY/y3z0uvOGX8cp1C2fiC4+ZmBhp6yZWkojtHL1YEMnRt1Y63HB9TM17proGEmeG7HeUY+UP36F0aknKYTpYA==", 148 | "dev": true, 149 | "license": "MIT", 150 | "engines": { 151 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 152 | } 153 | }, 154 | "node_modules/@eslint/object-schema": { 155 | "version": "2.1.6", 156 | "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", 157 | "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", 158 | "dev": true, 159 | "license": "Apache-2.0", 160 | "engines": { 161 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 162 | } 163 | }, 164 | "node_modules/@eslint/plugin-kit": { 165 | "version": "0.2.8", 166 | "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz", 167 | "integrity": "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==", 168 | "dev": true, 169 | "license": "Apache-2.0", 170 | "dependencies": { 171 | "@eslint/core": "^0.13.0", 172 | "levn": "^0.4.1" 173 | }, 174 | "engines": { 175 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 176 | } 177 | }, 178 | "node_modules/@eslint/plugin-kit/node_modules/@eslint/core": { 179 | "version": "0.13.0", 180 | "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz", 181 | "integrity": "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==", 182 | "dev": true, 183 | "license": "Apache-2.0", 184 | "dependencies": { 185 | "@types/json-schema": "^7.0.15" 186 | }, 187 | "engines": { 188 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 189 | } 190 | }, 191 | "node_modules/@humanfs/core": { 192 | "version": "0.19.1", 193 | "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", 194 | "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", 195 | "dev": true, 196 | "license": "Apache-2.0", 197 | "engines": { 198 | "node": ">=18.18.0" 199 | } 200 | }, 201 | "node_modules/@humanfs/node": { 202 | "version": "0.16.6", 203 | "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", 204 | "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", 205 | "dev": true, 206 | "license": "Apache-2.0", 207 | "dependencies": { 208 | "@humanfs/core": "^0.19.1", 209 | "@humanwhocodes/retry": "^0.3.0" 210 | }, 211 | "engines": { 212 | "node": ">=18.18.0" 213 | } 214 | }, 215 | "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { 216 | "version": "0.3.1", 217 | "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", 218 | "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", 219 | "dev": true, 220 | "license": "Apache-2.0", 221 | "engines": { 222 | "node": ">=18.18" 223 | }, 224 | "funding": { 225 | "type": "github", 226 | "url": "https://github.com/sponsors/nzakas" 227 | } 228 | }, 229 | "node_modules/@humanwhocodes/module-importer": { 230 | "version": "1.0.1", 231 | "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", 232 | "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", 233 | "dev": true, 234 | "license": "Apache-2.0", 235 | "engines": { 236 | "node": ">=12.22" 237 | }, 238 | "funding": { 239 | "type": "github", 240 | "url": "https://github.com/sponsors/nzakas" 241 | } 242 | }, 243 | "node_modules/@humanwhocodes/retry": { 244 | "version": "0.4.2", 245 | "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", 246 | "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", 247 | "dev": true, 248 | "license": "Apache-2.0", 249 | "engines": { 250 | "node": ">=18.18" 251 | }, 252 | "funding": { 253 | "type": "github", 254 | "url": "https://github.com/sponsors/nzakas" 255 | } 256 | }, 257 | "node_modules/@isaacs/cliui": { 258 | "version": "8.0.2", 259 | "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", 260 | "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", 261 | "dev": true, 262 | "license": "ISC", 263 | "dependencies": { 264 | "string-width": "^5.1.2", 265 | "string-width-cjs": "npm:string-width@^4.2.0", 266 | "strip-ansi": "^7.0.1", 267 | "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", 268 | "wrap-ansi": "^8.1.0", 269 | "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" 270 | }, 271 | "engines": { 272 | "node": ">=12" 273 | } 274 | }, 275 | "node_modules/@pkgjs/parseargs": { 276 | "version": "0.11.0", 277 | "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", 278 | "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", 279 | "dev": true, 280 | "license": "MIT", 281 | "optional": true, 282 | "engines": { 283 | "node": ">=14" 284 | } 285 | }, 286 | "node_modules/@pkgr/core": { 287 | "version": "0.1.2", 288 | "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.2.tgz", 289 | "integrity": "sha512-fdDH1LSGfZdTH2sxdpVMw31BanV28K/Gry0cVFxaNP77neJSkd82mM8ErPNYs9e+0O7SdHBLTDzDgwUuy18RnQ==", 290 | "dev": true, 291 | "license": "MIT", 292 | "engines": { 293 | "node": "^12.20.0 || ^14.18.0 || >=16.0.0" 294 | }, 295 | "funding": { 296 | "url": "https://opencollective.com/unts" 297 | } 298 | }, 299 | "node_modules/@types/estree": { 300 | "version": "1.0.7", 301 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", 302 | "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", 303 | "dev": true, 304 | "license": "MIT" 305 | }, 306 | "node_modules/@types/json-schema": { 307 | "version": "7.0.15", 308 | "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", 309 | "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", 310 | "dev": true, 311 | "license": "MIT" 312 | }, 313 | "node_modules/@types/luxon": { 314 | "version": "3.6.2", 315 | "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.6.2.tgz", 316 | "integrity": "sha512-R/BdP7OxEMc44l2Ex5lSXHoIXTB2JLNa3y2QISIbr58U/YcsffyQrYW//hZSdrfxrjRZj3GcUoxMPGdO8gSYuw==", 317 | "license": "MIT" 318 | }, 319 | "node_modules/acorn": { 320 | "version": "8.14.1", 321 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", 322 | "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", 323 | "dev": true, 324 | "license": "MIT", 325 | "bin": { 326 | "acorn": "bin/acorn" 327 | }, 328 | "engines": { 329 | "node": ">=0.4.0" 330 | } 331 | }, 332 | "node_modules/acorn-jsx": { 333 | "version": "5.3.2", 334 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", 335 | "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", 336 | "dev": true, 337 | "license": "MIT", 338 | "peerDependencies": { 339 | "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" 340 | } 341 | }, 342 | "node_modules/ajv": { 343 | "version": "6.12.6", 344 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 345 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 346 | "dev": true, 347 | "license": "MIT", 348 | "dependencies": { 349 | "fast-deep-equal": "^3.1.1", 350 | "fast-json-stable-stringify": "^2.0.0", 351 | "json-schema-traverse": "^0.4.1", 352 | "uri-js": "^4.2.2" 353 | }, 354 | "funding": { 355 | "type": "github", 356 | "url": "https://github.com/sponsors/epoberezkin" 357 | } 358 | }, 359 | "node_modules/ansi-colors": { 360 | "version": "4.1.3", 361 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", 362 | "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", 363 | "dev": true, 364 | "license": "MIT", 365 | "engines": { 366 | "node": ">=6" 367 | } 368 | }, 369 | "node_modules/ansi-regex": { 370 | "version": "6.1.0", 371 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", 372 | "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", 373 | "dev": true, 374 | "license": "MIT", 375 | "engines": { 376 | "node": ">=12" 377 | }, 378 | "funding": { 379 | "url": "https://github.com/chalk/ansi-regex?sponsor=1" 380 | } 381 | }, 382 | "node_modules/ansi-styles": { 383 | "version": "6.2.1", 384 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", 385 | "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", 386 | "dev": true, 387 | "license": "MIT", 388 | "engines": { 389 | "node": ">=12" 390 | }, 391 | "funding": { 392 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 393 | } 394 | }, 395 | "node_modules/anymatch": { 396 | "version": "3.1.3", 397 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", 398 | "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", 399 | "dev": true, 400 | "license": "ISC", 401 | "dependencies": { 402 | "normalize-path": "^3.0.0", 403 | "picomatch": "^2.0.4" 404 | }, 405 | "engines": { 406 | "node": ">= 8" 407 | } 408 | }, 409 | "node_modules/are-docs-informative": { 410 | "version": "0.0.2", 411 | "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", 412 | "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", 413 | "dev": true, 414 | "license": "MIT", 415 | "engines": { 416 | "node": ">=14" 417 | } 418 | }, 419 | "node_modules/argparse": { 420 | "version": "2.0.1", 421 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 422 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 423 | "dev": true, 424 | "license": "Python-2.0" 425 | }, 426 | "node_modules/assertion-error": { 427 | "version": "2.0.1", 428 | "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", 429 | "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", 430 | "dev": true, 431 | "license": "MIT", 432 | "engines": { 433 | "node": ">=12" 434 | } 435 | }, 436 | "node_modules/balanced-match": { 437 | "version": "1.0.2", 438 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 439 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 440 | "dev": true, 441 | "license": "MIT" 442 | }, 443 | "node_modules/binary-extensions": { 444 | "version": "2.3.0", 445 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", 446 | "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", 447 | "dev": true, 448 | "license": "MIT", 449 | "engines": { 450 | "node": ">=8" 451 | }, 452 | "funding": { 453 | "url": "https://github.com/sponsors/sindresorhus" 454 | } 455 | }, 456 | "node_modules/brace-expansion": { 457 | "version": "1.1.11", 458 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 459 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 460 | "dev": true, 461 | "license": "MIT", 462 | "dependencies": { 463 | "balanced-match": "^1.0.0", 464 | "concat-map": "0.0.1" 465 | } 466 | }, 467 | "node_modules/braces": { 468 | "version": "3.0.3", 469 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", 470 | "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", 471 | "dev": true, 472 | "license": "MIT", 473 | "dependencies": { 474 | "fill-range": "^7.1.1" 475 | }, 476 | "engines": { 477 | "node": ">=8" 478 | } 479 | }, 480 | "node_modules/browser-stdout": { 481 | "version": "1.3.1", 482 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", 483 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", 484 | "dev": true 485 | }, 486 | "node_modules/callsites": { 487 | "version": "3.1.0", 488 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 489 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 490 | "dev": true, 491 | "license": "MIT", 492 | "engines": { 493 | "node": ">=6" 494 | } 495 | }, 496 | "node_modules/camelcase": { 497 | "version": "6.2.0", 498 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", 499 | "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", 500 | "dev": true, 501 | "engines": { 502 | "node": ">=10" 503 | }, 504 | "funding": { 505 | "url": "https://github.com/sponsors/sindresorhus" 506 | } 507 | }, 508 | "node_modules/chai": { 509 | "version": "5.2.0", 510 | "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.0.tgz", 511 | "integrity": "sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==", 512 | "dev": true, 513 | "license": "MIT", 514 | "dependencies": { 515 | "assertion-error": "^2.0.1", 516 | "check-error": "^2.1.1", 517 | "deep-eql": "^5.0.1", 518 | "loupe": "^3.1.0", 519 | "pathval": "^2.0.0" 520 | }, 521 | "engines": { 522 | "node": ">=12" 523 | } 524 | }, 525 | "node_modules/chalk": { 526 | "version": "4.1.0", 527 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", 528 | "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", 529 | "dev": true, 530 | "dependencies": { 531 | "ansi-styles": "^4.1.0", 532 | "supports-color": "^7.1.0" 533 | }, 534 | "engines": { 535 | "node": ">=10" 536 | }, 537 | "funding": { 538 | "url": "https://github.com/chalk/chalk?sponsor=1" 539 | } 540 | }, 541 | "node_modules/chalk/node_modules/ansi-styles": { 542 | "version": "4.3.0", 543 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 544 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 545 | "dev": true, 546 | "dependencies": { 547 | "color-convert": "^2.0.1" 548 | }, 549 | "engines": { 550 | "node": ">=8" 551 | }, 552 | "funding": { 553 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 554 | } 555 | }, 556 | "node_modules/chalk/node_modules/has-flag": { 557 | "version": "4.0.0", 558 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 559 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 560 | "dev": true, 561 | "engines": { 562 | "node": ">=8" 563 | } 564 | }, 565 | "node_modules/chalk/node_modules/supports-color": { 566 | "version": "7.2.0", 567 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 568 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 569 | "dev": true, 570 | "dependencies": { 571 | "has-flag": "^4.0.0" 572 | }, 573 | "engines": { 574 | "node": ">=8" 575 | } 576 | }, 577 | "node_modules/check-error": { 578 | "version": "2.1.1", 579 | "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", 580 | "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", 581 | "dev": true, 582 | "license": "MIT", 583 | "engines": { 584 | "node": ">= 16" 585 | } 586 | }, 587 | "node_modules/chokidar": { 588 | "version": "3.6.0", 589 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", 590 | "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", 591 | "dev": true, 592 | "license": "MIT", 593 | "dependencies": { 594 | "anymatch": "~3.1.2", 595 | "braces": "~3.0.2", 596 | "glob-parent": "~5.1.2", 597 | "is-binary-path": "~2.1.0", 598 | "is-glob": "~4.0.1", 599 | "normalize-path": "~3.0.0", 600 | "readdirp": "~3.6.0" 601 | }, 602 | "engines": { 603 | "node": ">= 8.10.0" 604 | }, 605 | "funding": { 606 | "url": "https://paulmillr.com/funding/" 607 | }, 608 | "optionalDependencies": { 609 | "fsevents": "~2.3.2" 610 | } 611 | }, 612 | "node_modules/chokidar/node_modules/glob-parent": { 613 | "version": "5.1.2", 614 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 615 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 616 | "dev": true, 617 | "license": "ISC", 618 | "dependencies": { 619 | "is-glob": "^4.0.1" 620 | }, 621 | "engines": { 622 | "node": ">= 6" 623 | } 624 | }, 625 | "node_modules/cliui": { 626 | "version": "8.0.1", 627 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", 628 | "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", 629 | "dev": true, 630 | "license": "ISC", 631 | "dependencies": { 632 | "string-width": "^4.2.0", 633 | "strip-ansi": "^6.0.1", 634 | "wrap-ansi": "^7.0.0" 635 | }, 636 | "engines": { 637 | "node": ">=12" 638 | } 639 | }, 640 | "node_modules/cliui/node_modules/ansi-regex": { 641 | "version": "5.0.1", 642 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 643 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 644 | "dev": true, 645 | "license": "MIT", 646 | "engines": { 647 | "node": ">=8" 648 | } 649 | }, 650 | "node_modules/cliui/node_modules/ansi-styles": { 651 | "version": "4.3.0", 652 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 653 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 654 | "dev": true, 655 | "license": "MIT", 656 | "dependencies": { 657 | "color-convert": "^2.0.1" 658 | }, 659 | "engines": { 660 | "node": ">=8" 661 | }, 662 | "funding": { 663 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 664 | } 665 | }, 666 | "node_modules/cliui/node_modules/emoji-regex": { 667 | "version": "8.0.0", 668 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 669 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 670 | "dev": true, 671 | "license": "MIT" 672 | }, 673 | "node_modules/cliui/node_modules/string-width": { 674 | "version": "4.2.3", 675 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 676 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 677 | "dev": true, 678 | "license": "MIT", 679 | "dependencies": { 680 | "emoji-regex": "^8.0.0", 681 | "is-fullwidth-code-point": "^3.0.0", 682 | "strip-ansi": "^6.0.1" 683 | }, 684 | "engines": { 685 | "node": ">=8" 686 | } 687 | }, 688 | "node_modules/cliui/node_modules/strip-ansi": { 689 | "version": "6.0.1", 690 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 691 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 692 | "dev": true, 693 | "license": "MIT", 694 | "dependencies": { 695 | "ansi-regex": "^5.0.1" 696 | }, 697 | "engines": { 698 | "node": ">=8" 699 | } 700 | }, 701 | "node_modules/cliui/node_modules/wrap-ansi": { 702 | "version": "7.0.0", 703 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 704 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 705 | "dev": true, 706 | "license": "MIT", 707 | "dependencies": { 708 | "ansi-styles": "^4.0.0", 709 | "string-width": "^4.1.0", 710 | "strip-ansi": "^6.0.0" 711 | }, 712 | "engines": { 713 | "node": ">=10" 714 | }, 715 | "funding": { 716 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 717 | } 718 | }, 719 | "node_modules/color-convert": { 720 | "version": "2.0.1", 721 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 722 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 723 | "dev": true, 724 | "license": "MIT", 725 | "dependencies": { 726 | "color-name": "~1.1.4" 727 | }, 728 | "engines": { 729 | "node": ">=7.0.0" 730 | } 731 | }, 732 | "node_modules/color-name": { 733 | "version": "1.1.4", 734 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 735 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 736 | "dev": true, 737 | "license": "MIT" 738 | }, 739 | "node_modules/comment-parser": { 740 | "version": "1.4.1", 741 | "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", 742 | "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", 743 | "dev": true, 744 | "license": "MIT", 745 | "engines": { 746 | "node": ">= 12.0.0" 747 | } 748 | }, 749 | "node_modules/concat-map": { 750 | "version": "0.0.1", 751 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 752 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 753 | "dev": true, 754 | "license": "MIT" 755 | }, 756 | "node_modules/cron": { 757 | "version": "4.3.0", 758 | "resolved": "https://registry.npmjs.org/cron/-/cron-4.3.0.tgz", 759 | "integrity": "sha512-ciiYNLfSlF9MrDqnbMdRWFiA6oizSF7kA1osPP9lRzNu0Uu+AWog1UKy7SkckiDY2irrNjeO6qLyKnXC8oxmrw==", 760 | "license": "MIT", 761 | "dependencies": { 762 | "@types/luxon": "~3.6.0", 763 | "luxon": "~3.6.0" 764 | }, 765 | "engines": { 766 | "node": ">=18.x" 767 | } 768 | }, 769 | "node_modules/cross-spawn": { 770 | "version": "7.0.6", 771 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", 772 | "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", 773 | "dev": true, 774 | "license": "MIT", 775 | "dependencies": { 776 | "path-key": "^3.1.0", 777 | "shebang-command": "^2.0.0", 778 | "which": "^2.0.1" 779 | }, 780 | "engines": { 781 | "node": ">= 8" 782 | } 783 | }, 784 | "node_modules/debug": { 785 | "version": "4.4.0", 786 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", 787 | "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", 788 | "dev": true, 789 | "license": "MIT", 790 | "dependencies": { 791 | "ms": "^2.1.3" 792 | }, 793 | "engines": { 794 | "node": ">=6.0" 795 | }, 796 | "peerDependenciesMeta": { 797 | "supports-color": { 798 | "optional": true 799 | } 800 | } 801 | }, 802 | "node_modules/decamelize": { 803 | "version": "4.0.0", 804 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", 805 | "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", 806 | "dev": true, 807 | "engines": { 808 | "node": ">=10" 809 | }, 810 | "funding": { 811 | "url": "https://github.com/sponsors/sindresorhus" 812 | } 813 | }, 814 | "node_modules/deep-eql": { 815 | "version": "5.0.2", 816 | "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", 817 | "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", 818 | "dev": true, 819 | "license": "MIT", 820 | "engines": { 821 | "node": ">=6" 822 | } 823 | }, 824 | "node_modules/deep-is": { 825 | "version": "0.1.4", 826 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", 827 | "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", 828 | "dev": true, 829 | "license": "MIT" 830 | }, 831 | "node_modules/diff": { 832 | "version": "5.2.0", 833 | "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", 834 | "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", 835 | "dev": true, 836 | "license": "BSD-3-Clause", 837 | "engines": { 838 | "node": ">=0.3.1" 839 | } 840 | }, 841 | "node_modules/eastasianwidth": { 842 | "version": "0.2.0", 843 | "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", 844 | "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", 845 | "dev": true, 846 | "license": "MIT" 847 | }, 848 | "node_modules/emoji-regex": { 849 | "version": "9.2.2", 850 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", 851 | "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", 852 | "dev": true, 853 | "license": "MIT" 854 | }, 855 | "node_modules/es-module-lexer": { 856 | "version": "1.6.0", 857 | "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", 858 | "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", 859 | "dev": true, 860 | "license": "MIT" 861 | }, 862 | "node_modules/escalade": { 863 | "version": "3.2.0", 864 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", 865 | "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", 866 | "dev": true, 867 | "license": "MIT", 868 | "engines": { 869 | "node": ">=6" 870 | } 871 | }, 872 | "node_modules/escape-string-regexp": { 873 | "version": "4.0.0", 874 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 875 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 876 | "dev": true, 877 | "license": "MIT", 878 | "engines": { 879 | "node": ">=10" 880 | }, 881 | "funding": { 882 | "url": "https://github.com/sponsors/sindresorhus" 883 | } 884 | }, 885 | "node_modules/eslint": { 886 | "version": "9.24.0", 887 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.24.0.tgz", 888 | "integrity": "sha512-eh/jxIEJyZrvbWRe4XuVclLPDYSYYYgLy5zXGGxD6j8zjSAxFEzI2fL/8xNq6O2yKqVt+eF2YhV+hxjV6UKXwQ==", 889 | "dev": true, 890 | "license": "MIT", 891 | "dependencies": { 892 | "@eslint-community/eslint-utils": "^4.2.0", 893 | "@eslint-community/regexpp": "^4.12.1", 894 | "@eslint/config-array": "^0.20.0", 895 | "@eslint/config-helpers": "^0.2.0", 896 | "@eslint/core": "^0.12.0", 897 | "@eslint/eslintrc": "^3.3.1", 898 | "@eslint/js": "9.24.0", 899 | "@eslint/plugin-kit": "^0.2.7", 900 | "@humanfs/node": "^0.16.6", 901 | "@humanwhocodes/module-importer": "^1.0.1", 902 | "@humanwhocodes/retry": "^0.4.2", 903 | "@types/estree": "^1.0.6", 904 | "@types/json-schema": "^7.0.15", 905 | "ajv": "^6.12.4", 906 | "chalk": "^4.0.0", 907 | "cross-spawn": "^7.0.6", 908 | "debug": "^4.3.2", 909 | "escape-string-regexp": "^4.0.0", 910 | "eslint-scope": "^8.3.0", 911 | "eslint-visitor-keys": "^4.2.0", 912 | "espree": "^10.3.0", 913 | "esquery": "^1.5.0", 914 | "esutils": "^2.0.2", 915 | "fast-deep-equal": "^3.1.3", 916 | "file-entry-cache": "^8.0.0", 917 | "find-up": "^5.0.0", 918 | "glob-parent": "^6.0.2", 919 | "ignore": "^5.2.0", 920 | "imurmurhash": "^0.1.4", 921 | "is-glob": "^4.0.0", 922 | "json-stable-stringify-without-jsonify": "^1.0.1", 923 | "lodash.merge": "^4.6.2", 924 | "minimatch": "^3.1.2", 925 | "natural-compare": "^1.4.0", 926 | "optionator": "^0.9.3" 927 | }, 928 | "bin": { 929 | "eslint": "bin/eslint.js" 930 | }, 931 | "engines": { 932 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 933 | }, 934 | "funding": { 935 | "url": "https://eslint.org/donate" 936 | }, 937 | "peerDependencies": { 938 | "jiti": "*" 939 | }, 940 | "peerDependenciesMeta": { 941 | "jiti": { 942 | "optional": true 943 | } 944 | } 945 | }, 946 | "node_modules/eslint-config-prettier": { 947 | "version": "10.1.2", 948 | "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.2.tgz", 949 | "integrity": "sha512-Epgp/EofAUeEpIdZkW60MHKvPyru1ruQJxPL+WIycnaPApuseK0Zpkrh/FwL9oIpQvIhJwV7ptOy0DWUjTlCiA==", 950 | "dev": true, 951 | "license": "MIT", 952 | "bin": { 953 | "eslint-config-prettier": "bin/cli.js" 954 | }, 955 | "peerDependencies": { 956 | "eslint": ">=7.0.0" 957 | } 958 | }, 959 | "node_modules/eslint-plugin-jsdoc": { 960 | "version": "50.6.9", 961 | "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-50.6.9.tgz", 962 | "integrity": "sha512-7/nHu3FWD4QRG8tCVqcv+BfFtctUtEDWc29oeDXB4bwmDM2/r1ndl14AG/2DUntdqH7qmpvdemJKwb3R97/QEw==", 963 | "dev": true, 964 | "license": "BSD-3-Clause", 965 | "dependencies": { 966 | "@es-joy/jsdoccomment": "~0.49.0", 967 | "are-docs-informative": "^0.0.2", 968 | "comment-parser": "1.4.1", 969 | "debug": "^4.3.6", 970 | "escape-string-regexp": "^4.0.0", 971 | "espree": "^10.1.0", 972 | "esquery": "^1.6.0", 973 | "parse-imports": "^2.1.1", 974 | "semver": "^7.6.3", 975 | "spdx-expression-parse": "^4.0.0", 976 | "synckit": "^0.9.1" 977 | }, 978 | "engines": { 979 | "node": ">=18" 980 | }, 981 | "peerDependencies": { 982 | "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" 983 | } 984 | }, 985 | "node_modules/eslint-plugin-prettier": { 986 | "version": "5.2.6", 987 | "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.6.tgz", 988 | "integrity": "sha512-mUcf7QG2Tjk7H055Jk0lGBjbgDnfrvqjhXh9t2xLMSCjZVcw9Rb1V6sVNXO0th3jgeO7zllWPTNRil3JW94TnQ==", 989 | "dev": true, 990 | "license": "MIT", 991 | "dependencies": { 992 | "prettier-linter-helpers": "^1.0.0", 993 | "synckit": "^0.11.0" 994 | }, 995 | "engines": { 996 | "node": "^14.18.0 || >=16.0.0" 997 | }, 998 | "funding": { 999 | "url": "https://opencollective.com/eslint-plugin-prettier" 1000 | }, 1001 | "peerDependencies": { 1002 | "@types/eslint": ">=8.0.0", 1003 | "eslint": ">=8.0.0", 1004 | "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0", 1005 | "prettier": ">=3.0.0" 1006 | }, 1007 | "peerDependenciesMeta": { 1008 | "@types/eslint": { 1009 | "optional": true 1010 | }, 1011 | "eslint-config-prettier": { 1012 | "optional": true 1013 | } 1014 | } 1015 | }, 1016 | "node_modules/eslint-plugin-prettier/node_modules/@pkgr/core": { 1017 | "version": "0.2.4", 1018 | "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.4.tgz", 1019 | "integrity": "sha512-ROFF39F6ZrnzSUEmQQZUar0Jt4xVoP9WnDRdWwF4NNcXs3xBTLgBUDoOwW141y1jP+S8nahIbdxbFC7IShw9Iw==", 1020 | "dev": true, 1021 | "license": "MIT", 1022 | "engines": { 1023 | "node": "^12.20.0 || ^14.18.0 || >=16.0.0" 1024 | }, 1025 | "funding": { 1026 | "url": "https://opencollective.com/pkgr" 1027 | } 1028 | }, 1029 | "node_modules/eslint-plugin-prettier/node_modules/synckit": { 1030 | "version": "0.11.4", 1031 | "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.4.tgz", 1032 | "integrity": "sha512-Q/XQKRaJiLiFIBNN+mndW7S/RHxvwzuZS6ZwmRzUBqJBv/5QIKCEwkBC8GBf8EQJKYnaFs0wOZbKTXBPj8L9oQ==", 1033 | "dev": true, 1034 | "license": "MIT", 1035 | "dependencies": { 1036 | "@pkgr/core": "^0.2.3", 1037 | "tslib": "^2.8.1" 1038 | }, 1039 | "engines": { 1040 | "node": "^14.18.0 || >=16.0.0" 1041 | }, 1042 | "funding": { 1043 | "url": "https://opencollective.com/synckit" 1044 | } 1045 | }, 1046 | "node_modules/eslint-scope": { 1047 | "version": "8.3.0", 1048 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz", 1049 | "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==", 1050 | "dev": true, 1051 | "license": "BSD-2-Clause", 1052 | "dependencies": { 1053 | "esrecurse": "^4.3.0", 1054 | "estraverse": "^5.2.0" 1055 | }, 1056 | "engines": { 1057 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1058 | }, 1059 | "funding": { 1060 | "url": "https://opencollective.com/eslint" 1061 | } 1062 | }, 1063 | "node_modules/eslint-visitor-keys": { 1064 | "version": "4.2.0", 1065 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", 1066 | "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", 1067 | "dev": true, 1068 | "license": "Apache-2.0", 1069 | "engines": { 1070 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1071 | }, 1072 | "funding": { 1073 | "url": "https://opencollective.com/eslint" 1074 | } 1075 | }, 1076 | "node_modules/espree": { 1077 | "version": "10.3.0", 1078 | "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", 1079 | "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", 1080 | "dev": true, 1081 | "license": "BSD-2-Clause", 1082 | "dependencies": { 1083 | "acorn": "^8.14.0", 1084 | "acorn-jsx": "^5.3.2", 1085 | "eslint-visitor-keys": "^4.2.0" 1086 | }, 1087 | "engines": { 1088 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1089 | }, 1090 | "funding": { 1091 | "url": "https://opencollective.com/eslint" 1092 | } 1093 | }, 1094 | "node_modules/esquery": { 1095 | "version": "1.6.0", 1096 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", 1097 | "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", 1098 | "dev": true, 1099 | "license": "BSD-3-Clause", 1100 | "dependencies": { 1101 | "estraverse": "^5.1.0" 1102 | }, 1103 | "engines": { 1104 | "node": ">=0.10" 1105 | } 1106 | }, 1107 | "node_modules/esrecurse": { 1108 | "version": "4.3.0", 1109 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", 1110 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", 1111 | "dev": true, 1112 | "license": "BSD-2-Clause", 1113 | "dependencies": { 1114 | "estraverse": "^5.2.0" 1115 | }, 1116 | "engines": { 1117 | "node": ">=4.0" 1118 | } 1119 | }, 1120 | "node_modules/estraverse": { 1121 | "version": "5.3.0", 1122 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", 1123 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", 1124 | "dev": true, 1125 | "license": "BSD-2-Clause", 1126 | "engines": { 1127 | "node": ">=4.0" 1128 | } 1129 | }, 1130 | "node_modules/esutils": { 1131 | "version": "2.0.3", 1132 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 1133 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 1134 | "dev": true, 1135 | "license": "BSD-2-Clause", 1136 | "engines": { 1137 | "node": ">=0.10.0" 1138 | } 1139 | }, 1140 | "node_modules/fast-deep-equal": { 1141 | "version": "3.1.3", 1142 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 1143 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 1144 | "dev": true, 1145 | "license": "MIT" 1146 | }, 1147 | "node_modules/fast-diff": { 1148 | "version": "1.2.0", 1149 | "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", 1150 | "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", 1151 | "dev": true 1152 | }, 1153 | "node_modules/fast-json-stable-stringify": { 1154 | "version": "2.1.0", 1155 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 1156 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 1157 | "dev": true, 1158 | "license": "MIT" 1159 | }, 1160 | "node_modules/fast-levenshtein": { 1161 | "version": "2.0.6", 1162 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 1163 | "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", 1164 | "dev": true, 1165 | "license": "MIT" 1166 | }, 1167 | "node_modules/file-entry-cache": { 1168 | "version": "8.0.0", 1169 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", 1170 | "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", 1171 | "dev": true, 1172 | "license": "MIT", 1173 | "dependencies": { 1174 | "flat-cache": "^4.0.0" 1175 | }, 1176 | "engines": { 1177 | "node": ">=16.0.0" 1178 | } 1179 | }, 1180 | "node_modules/fill-range": { 1181 | "version": "7.1.1", 1182 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", 1183 | "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", 1184 | "dev": true, 1185 | "license": "MIT", 1186 | "dependencies": { 1187 | "to-regex-range": "^5.0.1" 1188 | }, 1189 | "engines": { 1190 | "node": ">=8" 1191 | } 1192 | }, 1193 | "node_modules/find-up": { 1194 | "version": "5.0.0", 1195 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 1196 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 1197 | "dev": true, 1198 | "dependencies": { 1199 | "locate-path": "^6.0.0", 1200 | "path-exists": "^4.0.0" 1201 | }, 1202 | "engines": { 1203 | "node": ">=10" 1204 | }, 1205 | "funding": { 1206 | "url": "https://github.com/sponsors/sindresorhus" 1207 | } 1208 | }, 1209 | "node_modules/flat": { 1210 | "version": "5.0.2", 1211 | "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", 1212 | "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", 1213 | "dev": true, 1214 | "bin": { 1215 | "flat": "cli.js" 1216 | } 1217 | }, 1218 | "node_modules/flat-cache": { 1219 | "version": "4.0.1", 1220 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", 1221 | "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", 1222 | "dev": true, 1223 | "license": "MIT", 1224 | "dependencies": { 1225 | "flatted": "^3.2.9", 1226 | "keyv": "^4.5.4" 1227 | }, 1228 | "engines": { 1229 | "node": ">=16" 1230 | } 1231 | }, 1232 | "node_modules/flatted": { 1233 | "version": "3.3.3", 1234 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", 1235 | "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", 1236 | "dev": true, 1237 | "license": "ISC" 1238 | }, 1239 | "node_modules/foreground-child": { 1240 | "version": "3.3.1", 1241 | "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", 1242 | "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", 1243 | "dev": true, 1244 | "license": "ISC", 1245 | "dependencies": { 1246 | "cross-spawn": "^7.0.6", 1247 | "signal-exit": "^4.0.1" 1248 | }, 1249 | "engines": { 1250 | "node": ">=14" 1251 | }, 1252 | "funding": { 1253 | "url": "https://github.com/sponsors/isaacs" 1254 | } 1255 | }, 1256 | "node_modules/get-caller-file": { 1257 | "version": "2.0.5", 1258 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 1259 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 1260 | "dev": true, 1261 | "license": "ISC", 1262 | "engines": { 1263 | "node": "6.* || 8.* || >= 10.*" 1264 | } 1265 | }, 1266 | "node_modules/glob": { 1267 | "version": "10.4.5", 1268 | "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", 1269 | "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", 1270 | "dev": true, 1271 | "license": "ISC", 1272 | "dependencies": { 1273 | "foreground-child": "^3.1.0", 1274 | "jackspeak": "^3.1.2", 1275 | "minimatch": "^9.0.4", 1276 | "minipass": "^7.1.2", 1277 | "package-json-from-dist": "^1.0.0", 1278 | "path-scurry": "^1.11.1" 1279 | }, 1280 | "bin": { 1281 | "glob": "dist/esm/bin.mjs" 1282 | }, 1283 | "funding": { 1284 | "url": "https://github.com/sponsors/isaacs" 1285 | } 1286 | }, 1287 | "node_modules/glob-parent": { 1288 | "version": "6.0.2", 1289 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", 1290 | "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", 1291 | "dev": true, 1292 | "license": "ISC", 1293 | "dependencies": { 1294 | "is-glob": "^4.0.3" 1295 | }, 1296 | "engines": { 1297 | "node": ">=10.13.0" 1298 | } 1299 | }, 1300 | "node_modules/glob/node_modules/brace-expansion": { 1301 | "version": "2.0.1", 1302 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", 1303 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", 1304 | "dev": true, 1305 | "license": "MIT", 1306 | "dependencies": { 1307 | "balanced-match": "^1.0.0" 1308 | } 1309 | }, 1310 | "node_modules/glob/node_modules/minimatch": { 1311 | "version": "9.0.5", 1312 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", 1313 | "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", 1314 | "dev": true, 1315 | "license": "ISC", 1316 | "dependencies": { 1317 | "brace-expansion": "^2.0.1" 1318 | }, 1319 | "engines": { 1320 | "node": ">=16 || 14 >=14.17" 1321 | }, 1322 | "funding": { 1323 | "url": "https://github.com/sponsors/isaacs" 1324 | } 1325 | }, 1326 | "node_modules/globals": { 1327 | "version": "14.0.0", 1328 | "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", 1329 | "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", 1330 | "dev": true, 1331 | "license": "MIT", 1332 | "engines": { 1333 | "node": ">=18" 1334 | }, 1335 | "funding": { 1336 | "url": "https://github.com/sponsors/sindresorhus" 1337 | } 1338 | }, 1339 | "node_modules/he": { 1340 | "version": "1.2.0", 1341 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", 1342 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", 1343 | "dev": true, 1344 | "bin": { 1345 | "he": "bin/he" 1346 | } 1347 | }, 1348 | "node_modules/ignore": { 1349 | "version": "5.3.2", 1350 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", 1351 | "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", 1352 | "dev": true, 1353 | "license": "MIT", 1354 | "engines": { 1355 | "node": ">= 4" 1356 | } 1357 | }, 1358 | "node_modules/import-fresh": { 1359 | "version": "3.3.1", 1360 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", 1361 | "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", 1362 | "dev": true, 1363 | "license": "MIT", 1364 | "dependencies": { 1365 | "parent-module": "^1.0.0", 1366 | "resolve-from": "^4.0.0" 1367 | }, 1368 | "engines": { 1369 | "node": ">=6" 1370 | }, 1371 | "funding": { 1372 | "url": "https://github.com/sponsors/sindresorhus" 1373 | } 1374 | }, 1375 | "node_modules/imurmurhash": { 1376 | "version": "0.1.4", 1377 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 1378 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", 1379 | "dev": true, 1380 | "engines": { 1381 | "node": ">=0.8.19" 1382 | } 1383 | }, 1384 | "node_modules/is-binary-path": { 1385 | "version": "2.1.0", 1386 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 1387 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 1388 | "dev": true, 1389 | "license": "MIT", 1390 | "dependencies": { 1391 | "binary-extensions": "^2.0.0" 1392 | }, 1393 | "engines": { 1394 | "node": ">=8" 1395 | } 1396 | }, 1397 | "node_modules/is-extglob": { 1398 | "version": "2.1.1", 1399 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 1400 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", 1401 | "dev": true, 1402 | "engines": { 1403 | "node": ">=0.10.0" 1404 | } 1405 | }, 1406 | "node_modules/is-fullwidth-code-point": { 1407 | "version": "3.0.0", 1408 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 1409 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 1410 | "dev": true, 1411 | "license": "MIT", 1412 | "engines": { 1413 | "node": ">=8" 1414 | } 1415 | }, 1416 | "node_modules/is-glob": { 1417 | "version": "4.0.3", 1418 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 1419 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 1420 | "dev": true, 1421 | "license": "MIT", 1422 | "dependencies": { 1423 | "is-extglob": "^2.1.1" 1424 | }, 1425 | "engines": { 1426 | "node": ">=0.10.0" 1427 | } 1428 | }, 1429 | "node_modules/is-number": { 1430 | "version": "7.0.0", 1431 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 1432 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 1433 | "dev": true, 1434 | "license": "MIT", 1435 | "engines": { 1436 | "node": ">=0.12.0" 1437 | } 1438 | }, 1439 | "node_modules/is-plain-obj": { 1440 | "version": "2.1.0", 1441 | "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", 1442 | "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", 1443 | "dev": true, 1444 | "engines": { 1445 | "node": ">=8" 1446 | } 1447 | }, 1448 | "node_modules/is-unicode-supported": { 1449 | "version": "0.1.0", 1450 | "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", 1451 | "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", 1452 | "dev": true, 1453 | "license": "MIT", 1454 | "engines": { 1455 | "node": ">=10" 1456 | }, 1457 | "funding": { 1458 | "url": "https://github.com/sponsors/sindresorhus" 1459 | } 1460 | }, 1461 | "node_modules/isexe": { 1462 | "version": "2.0.0", 1463 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 1464 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 1465 | "dev": true, 1466 | "license": "ISC" 1467 | }, 1468 | "node_modules/jackspeak": { 1469 | "version": "3.4.3", 1470 | "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", 1471 | "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", 1472 | "dev": true, 1473 | "license": "BlueOak-1.0.0", 1474 | "dependencies": { 1475 | "@isaacs/cliui": "^8.0.2" 1476 | }, 1477 | "funding": { 1478 | "url": "https://github.com/sponsors/isaacs" 1479 | }, 1480 | "optionalDependencies": { 1481 | "@pkgjs/parseargs": "^0.11.0" 1482 | } 1483 | }, 1484 | "node_modules/js-yaml": { 1485 | "version": "4.1.0", 1486 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", 1487 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", 1488 | "dev": true, 1489 | "license": "MIT", 1490 | "dependencies": { 1491 | "argparse": "^2.0.1" 1492 | }, 1493 | "bin": { 1494 | "js-yaml": "bin/js-yaml.js" 1495 | } 1496 | }, 1497 | "node_modules/jsdoc-type-pratt-parser": { 1498 | "version": "4.1.0", 1499 | "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz", 1500 | "integrity": "sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==", 1501 | "dev": true, 1502 | "license": "MIT", 1503 | "engines": { 1504 | "node": ">=12.0.0" 1505 | } 1506 | }, 1507 | "node_modules/json-buffer": { 1508 | "version": "3.0.1", 1509 | "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", 1510 | "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", 1511 | "dev": true, 1512 | "license": "MIT" 1513 | }, 1514 | "node_modules/json-schema-traverse": { 1515 | "version": "0.4.1", 1516 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 1517 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 1518 | "dev": true, 1519 | "license": "MIT" 1520 | }, 1521 | "node_modules/json-stable-stringify-without-jsonify": { 1522 | "version": "1.0.1", 1523 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 1524 | "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", 1525 | "dev": true 1526 | }, 1527 | "node_modules/keyv": { 1528 | "version": "4.5.4", 1529 | "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", 1530 | "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", 1531 | "dev": true, 1532 | "license": "MIT", 1533 | "dependencies": { 1534 | "json-buffer": "3.0.1" 1535 | } 1536 | }, 1537 | "node_modules/levn": { 1538 | "version": "0.4.1", 1539 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", 1540 | "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", 1541 | "dev": true, 1542 | "license": "MIT", 1543 | "dependencies": { 1544 | "prelude-ls": "^1.2.1", 1545 | "type-check": "~0.4.0" 1546 | }, 1547 | "engines": { 1548 | "node": ">= 0.8.0" 1549 | } 1550 | }, 1551 | "node_modules/locate-path": { 1552 | "version": "6.0.0", 1553 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 1554 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 1555 | "dev": true, 1556 | "dependencies": { 1557 | "p-locate": "^5.0.0" 1558 | }, 1559 | "engines": { 1560 | "node": ">=10" 1561 | }, 1562 | "funding": { 1563 | "url": "https://github.com/sponsors/sindresorhus" 1564 | } 1565 | }, 1566 | "node_modules/lodash.merge": { 1567 | "version": "4.6.2", 1568 | "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", 1569 | "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", 1570 | "dev": true, 1571 | "license": "MIT" 1572 | }, 1573 | "node_modules/log-symbols": { 1574 | "version": "4.1.0", 1575 | "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", 1576 | "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", 1577 | "dev": true, 1578 | "license": "MIT", 1579 | "dependencies": { 1580 | "chalk": "^4.1.0", 1581 | "is-unicode-supported": "^0.1.0" 1582 | }, 1583 | "engines": { 1584 | "node": ">=10" 1585 | }, 1586 | "funding": { 1587 | "url": "https://github.com/sponsors/sindresorhus" 1588 | } 1589 | }, 1590 | "node_modules/loupe": { 1591 | "version": "3.1.3", 1592 | "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.3.tgz", 1593 | "integrity": "sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==", 1594 | "dev": true, 1595 | "license": "MIT" 1596 | }, 1597 | "node_modules/lru-cache": { 1598 | "version": "10.4.3", 1599 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", 1600 | "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", 1601 | "dev": true, 1602 | "license": "ISC" 1603 | }, 1604 | "node_modules/luxon": { 1605 | "version": "3.6.1", 1606 | "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.6.1.tgz", 1607 | "integrity": "sha512-tJLxrKJhO2ukZ5z0gyjY1zPh3Rh88Ej9P7jNrZiHMUXHae1yvI2imgOZtL1TO8TW6biMMKfTtAOoEJANgtWBMQ==", 1608 | "license": "MIT", 1609 | "engines": { 1610 | "node": ">=12" 1611 | } 1612 | }, 1613 | "node_modules/minimatch": { 1614 | "version": "3.1.2", 1615 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 1616 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 1617 | "dev": true, 1618 | "license": "ISC", 1619 | "dependencies": { 1620 | "brace-expansion": "^1.1.7" 1621 | }, 1622 | "engines": { 1623 | "node": "*" 1624 | } 1625 | }, 1626 | "node_modules/minipass": { 1627 | "version": "7.1.2", 1628 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", 1629 | "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", 1630 | "dev": true, 1631 | "license": "ISC", 1632 | "engines": { 1633 | "node": ">=16 || 14 >=14.17" 1634 | } 1635 | }, 1636 | "node_modules/mocha": { 1637 | "version": "11.1.0", 1638 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.1.0.tgz", 1639 | "integrity": "sha512-8uJR5RTC2NgpY3GrYcgpZrsEd9zKbPDpob1RezyR2upGHRQtHWofmzTMzTMSV6dru3tj5Ukt0+Vnq1qhFEEwAg==", 1640 | "dev": true, 1641 | "license": "MIT", 1642 | "dependencies": { 1643 | "ansi-colors": "^4.1.3", 1644 | "browser-stdout": "^1.3.1", 1645 | "chokidar": "^3.5.3", 1646 | "debug": "^4.3.5", 1647 | "diff": "^5.2.0", 1648 | "escape-string-regexp": "^4.0.0", 1649 | "find-up": "^5.0.0", 1650 | "glob": "^10.4.5", 1651 | "he": "^1.2.0", 1652 | "js-yaml": "^4.1.0", 1653 | "log-symbols": "^4.1.0", 1654 | "minimatch": "^5.1.6", 1655 | "ms": "^2.1.3", 1656 | "serialize-javascript": "^6.0.2", 1657 | "strip-json-comments": "^3.1.1", 1658 | "supports-color": "^8.1.1", 1659 | "workerpool": "^6.5.1", 1660 | "yargs": "^17.7.2", 1661 | "yargs-parser": "^21.1.1", 1662 | "yargs-unparser": "^2.0.0" 1663 | }, 1664 | "bin": { 1665 | "_mocha": "bin/_mocha", 1666 | "mocha": "bin/mocha.js" 1667 | }, 1668 | "engines": { 1669 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1670 | } 1671 | }, 1672 | "node_modules/mocha/node_modules/brace-expansion": { 1673 | "version": "2.0.1", 1674 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", 1675 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", 1676 | "dev": true, 1677 | "license": "MIT", 1678 | "dependencies": { 1679 | "balanced-match": "^1.0.0" 1680 | } 1681 | }, 1682 | "node_modules/mocha/node_modules/has-flag": { 1683 | "version": "4.0.0", 1684 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 1685 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 1686 | "dev": true, 1687 | "engines": { 1688 | "node": ">=8" 1689 | } 1690 | }, 1691 | "node_modules/mocha/node_modules/minimatch": { 1692 | "version": "5.1.6", 1693 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", 1694 | "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", 1695 | "dev": true, 1696 | "license": "ISC", 1697 | "dependencies": { 1698 | "brace-expansion": "^2.0.1" 1699 | }, 1700 | "engines": { 1701 | "node": ">=10" 1702 | } 1703 | }, 1704 | "node_modules/mocha/node_modules/supports-color": { 1705 | "version": "8.1.1", 1706 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", 1707 | "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", 1708 | "dev": true, 1709 | "dependencies": { 1710 | "has-flag": "^4.0.0" 1711 | }, 1712 | "engines": { 1713 | "node": ">=10" 1714 | }, 1715 | "funding": { 1716 | "url": "https://github.com/chalk/supports-color?sponsor=1" 1717 | } 1718 | }, 1719 | "node_modules/module-alias": { 1720 | "version": "2.2.3", 1721 | "resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.2.3.tgz", 1722 | "integrity": "sha512-23g5BFj4zdQL/b6tor7Ji+QY4pEfNH784BMslY9Qb0UnJWRAt+lQGLYmRaM0KDBwIG23ffEBELhZDP2rhi9f/Q==", 1723 | "dev": true, 1724 | "license": "MIT" 1725 | }, 1726 | "node_modules/ms": { 1727 | "version": "2.1.3", 1728 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1729 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 1730 | "dev": true, 1731 | "license": "MIT" 1732 | }, 1733 | "node_modules/natural-compare": { 1734 | "version": "1.4.0", 1735 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 1736 | "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", 1737 | "dev": true 1738 | }, 1739 | "node_modules/normalize-path": { 1740 | "version": "3.0.0", 1741 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 1742 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 1743 | "dev": true, 1744 | "license": "MIT", 1745 | "engines": { 1746 | "node": ">=0.10.0" 1747 | } 1748 | }, 1749 | "node_modules/optionator": { 1750 | "version": "0.9.4", 1751 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", 1752 | "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", 1753 | "dev": true, 1754 | "license": "MIT", 1755 | "dependencies": { 1756 | "deep-is": "^0.1.3", 1757 | "fast-levenshtein": "^2.0.6", 1758 | "levn": "^0.4.1", 1759 | "prelude-ls": "^1.2.1", 1760 | "type-check": "^0.4.0", 1761 | "word-wrap": "^1.2.5" 1762 | }, 1763 | "engines": { 1764 | "node": ">= 0.8.0" 1765 | } 1766 | }, 1767 | "node_modules/p-limit": { 1768 | "version": "3.1.0", 1769 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 1770 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 1771 | "dev": true, 1772 | "dependencies": { 1773 | "yocto-queue": "^0.1.0" 1774 | }, 1775 | "engines": { 1776 | "node": ">=10" 1777 | }, 1778 | "funding": { 1779 | "url": "https://github.com/sponsors/sindresorhus" 1780 | } 1781 | }, 1782 | "node_modules/p-locate": { 1783 | "version": "5.0.0", 1784 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 1785 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 1786 | "dev": true, 1787 | "dependencies": { 1788 | "p-limit": "^3.0.2" 1789 | }, 1790 | "engines": { 1791 | "node": ">=10" 1792 | }, 1793 | "funding": { 1794 | "url": "https://github.com/sponsors/sindresorhus" 1795 | } 1796 | }, 1797 | "node_modules/package-json-from-dist": { 1798 | "version": "1.0.1", 1799 | "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", 1800 | "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", 1801 | "dev": true, 1802 | "license": "BlueOak-1.0.0" 1803 | }, 1804 | "node_modules/parent-module": { 1805 | "version": "1.0.1", 1806 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 1807 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 1808 | "dev": true, 1809 | "license": "MIT", 1810 | "dependencies": { 1811 | "callsites": "^3.0.0" 1812 | }, 1813 | "engines": { 1814 | "node": ">=6" 1815 | } 1816 | }, 1817 | "node_modules/parse-imports": { 1818 | "version": "2.2.1", 1819 | "resolved": "https://registry.npmjs.org/parse-imports/-/parse-imports-2.2.1.tgz", 1820 | "integrity": "sha512-OL/zLggRp8mFhKL0rNORUTR4yBYujK/uU+xZL+/0Rgm2QE4nLO9v8PzEweSJEbMGKmDRjJE4R3IMJlL2di4JeQ==", 1821 | "dev": true, 1822 | "license": "Apache-2.0 AND MIT", 1823 | "dependencies": { 1824 | "es-module-lexer": "^1.5.3", 1825 | "slashes": "^3.0.12" 1826 | }, 1827 | "engines": { 1828 | "node": ">= 18" 1829 | } 1830 | }, 1831 | "node_modules/path-exists": { 1832 | "version": "4.0.0", 1833 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 1834 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 1835 | "dev": true, 1836 | "engines": { 1837 | "node": ">=8" 1838 | } 1839 | }, 1840 | "node_modules/path-key": { 1841 | "version": "3.1.1", 1842 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 1843 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 1844 | "dev": true, 1845 | "license": "MIT", 1846 | "engines": { 1847 | "node": ">=8" 1848 | } 1849 | }, 1850 | "node_modules/path-scurry": { 1851 | "version": "1.11.1", 1852 | "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", 1853 | "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", 1854 | "dev": true, 1855 | "license": "BlueOak-1.0.0", 1856 | "dependencies": { 1857 | "lru-cache": "^10.2.0", 1858 | "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" 1859 | }, 1860 | "engines": { 1861 | "node": ">=16 || 14 >=14.18" 1862 | }, 1863 | "funding": { 1864 | "url": "https://github.com/sponsors/isaacs" 1865 | } 1866 | }, 1867 | "node_modules/pathval": { 1868 | "version": "2.0.0", 1869 | "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", 1870 | "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", 1871 | "dev": true, 1872 | "license": "MIT", 1873 | "engines": { 1874 | "node": ">= 14.16" 1875 | } 1876 | }, 1877 | "node_modules/picomatch": { 1878 | "version": "2.3.1", 1879 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 1880 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 1881 | "dev": true, 1882 | "license": "MIT", 1883 | "engines": { 1884 | "node": ">=8.6" 1885 | }, 1886 | "funding": { 1887 | "url": "https://github.com/sponsors/jonschlinkert" 1888 | } 1889 | }, 1890 | "node_modules/prelude-ls": { 1891 | "version": "1.2.1", 1892 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", 1893 | "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", 1894 | "dev": true, 1895 | "license": "MIT", 1896 | "engines": { 1897 | "node": ">= 0.8.0" 1898 | } 1899 | }, 1900 | "node_modules/prettier": { 1901 | "version": "3.5.3", 1902 | "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz", 1903 | "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", 1904 | "dev": true, 1905 | "license": "MIT", 1906 | "bin": { 1907 | "prettier": "bin/prettier.cjs" 1908 | }, 1909 | "engines": { 1910 | "node": ">=14" 1911 | }, 1912 | "funding": { 1913 | "url": "https://github.com/prettier/prettier?sponsor=1" 1914 | } 1915 | }, 1916 | "node_modules/prettier-linter-helpers": { 1917 | "version": "1.0.0", 1918 | "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", 1919 | "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", 1920 | "dev": true, 1921 | "dependencies": { 1922 | "fast-diff": "^1.1.2" 1923 | }, 1924 | "engines": { 1925 | "node": ">=6.0.0" 1926 | } 1927 | }, 1928 | "node_modules/punycode": { 1929 | "version": "2.3.1", 1930 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", 1931 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", 1932 | "dev": true, 1933 | "license": "MIT", 1934 | "engines": { 1935 | "node": ">=6" 1936 | } 1937 | }, 1938 | "node_modules/randombytes": { 1939 | "version": "2.1.0", 1940 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", 1941 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", 1942 | "dev": true, 1943 | "license": "MIT", 1944 | "dependencies": { 1945 | "safe-buffer": "^5.1.0" 1946 | } 1947 | }, 1948 | "node_modules/readdirp": { 1949 | "version": "3.6.0", 1950 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", 1951 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", 1952 | "dev": true, 1953 | "license": "MIT", 1954 | "dependencies": { 1955 | "picomatch": "^2.2.1" 1956 | }, 1957 | "engines": { 1958 | "node": ">=8.10.0" 1959 | } 1960 | }, 1961 | "node_modules/require-directory": { 1962 | "version": "2.1.1", 1963 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 1964 | "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", 1965 | "dev": true, 1966 | "license": "MIT", 1967 | "engines": { 1968 | "node": ">=0.10.0" 1969 | } 1970 | }, 1971 | "node_modules/resolve-from": { 1972 | "version": "4.0.0", 1973 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 1974 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 1975 | "dev": true, 1976 | "license": "MIT", 1977 | "engines": { 1978 | "node": ">=4" 1979 | } 1980 | }, 1981 | "node_modules/safe-buffer": { 1982 | "version": "5.2.1", 1983 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1984 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 1985 | "dev": true, 1986 | "funding": [ 1987 | { 1988 | "type": "github", 1989 | "url": "https://github.com/sponsors/feross" 1990 | }, 1991 | { 1992 | "type": "patreon", 1993 | "url": "https://www.patreon.com/feross" 1994 | }, 1995 | { 1996 | "type": "consulting", 1997 | "url": "https://feross.org/support" 1998 | } 1999 | ], 2000 | "license": "MIT" 2001 | }, 2002 | "node_modules/semver": { 2003 | "version": "7.7.1", 2004 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", 2005 | "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", 2006 | "dev": true, 2007 | "license": "ISC", 2008 | "bin": { 2009 | "semver": "bin/semver.js" 2010 | }, 2011 | "engines": { 2012 | "node": ">=10" 2013 | } 2014 | }, 2015 | "node_modules/serialize-javascript": { 2016 | "version": "6.0.2", 2017 | "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", 2018 | "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", 2019 | "dev": true, 2020 | "license": "BSD-3-Clause", 2021 | "dependencies": { 2022 | "randombytes": "^2.1.0" 2023 | } 2024 | }, 2025 | "node_modules/shebang-command": { 2026 | "version": "2.0.0", 2027 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 2028 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 2029 | "dev": true, 2030 | "license": "MIT", 2031 | "dependencies": { 2032 | "shebang-regex": "^3.0.0" 2033 | }, 2034 | "engines": { 2035 | "node": ">=8" 2036 | } 2037 | }, 2038 | "node_modules/shebang-regex": { 2039 | "version": "3.0.0", 2040 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 2041 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 2042 | "dev": true, 2043 | "license": "MIT", 2044 | "engines": { 2045 | "node": ">=8" 2046 | } 2047 | }, 2048 | "node_modules/signal-exit": { 2049 | "version": "4.1.0", 2050 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", 2051 | "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", 2052 | "dev": true, 2053 | "license": "ISC", 2054 | "engines": { 2055 | "node": ">=14" 2056 | }, 2057 | "funding": { 2058 | "url": "https://github.com/sponsors/isaacs" 2059 | } 2060 | }, 2061 | "node_modules/slashes": { 2062 | "version": "3.0.12", 2063 | "resolved": "https://registry.npmjs.org/slashes/-/slashes-3.0.12.tgz", 2064 | "integrity": "sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==", 2065 | "dev": true, 2066 | "license": "ISC" 2067 | }, 2068 | "node_modules/spdx-exceptions": { 2069 | "version": "2.5.0", 2070 | "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", 2071 | "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", 2072 | "dev": true, 2073 | "license": "CC-BY-3.0" 2074 | }, 2075 | "node_modules/spdx-expression-parse": { 2076 | "version": "4.0.0", 2077 | "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", 2078 | "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", 2079 | "dev": true, 2080 | "license": "MIT", 2081 | "dependencies": { 2082 | "spdx-exceptions": "^2.1.0", 2083 | "spdx-license-ids": "^3.0.0" 2084 | } 2085 | }, 2086 | "node_modules/spdx-license-ids": { 2087 | "version": "3.0.21", 2088 | "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz", 2089 | "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==", 2090 | "dev": true, 2091 | "license": "CC0-1.0" 2092 | }, 2093 | "node_modules/string-width": { 2094 | "version": "5.1.2", 2095 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", 2096 | "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", 2097 | "dev": true, 2098 | "license": "MIT", 2099 | "dependencies": { 2100 | "eastasianwidth": "^0.2.0", 2101 | "emoji-regex": "^9.2.2", 2102 | "strip-ansi": "^7.0.1" 2103 | }, 2104 | "engines": { 2105 | "node": ">=12" 2106 | }, 2107 | "funding": { 2108 | "url": "https://github.com/sponsors/sindresorhus" 2109 | } 2110 | }, 2111 | "node_modules/string-width-cjs": { 2112 | "name": "string-width", 2113 | "version": "4.2.3", 2114 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 2115 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 2116 | "dev": true, 2117 | "license": "MIT", 2118 | "dependencies": { 2119 | "emoji-regex": "^8.0.0", 2120 | "is-fullwidth-code-point": "^3.0.0", 2121 | "strip-ansi": "^6.0.1" 2122 | }, 2123 | "engines": { 2124 | "node": ">=8" 2125 | } 2126 | }, 2127 | "node_modules/string-width-cjs/node_modules/ansi-regex": { 2128 | "version": "5.0.1", 2129 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 2130 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 2131 | "dev": true, 2132 | "license": "MIT", 2133 | "engines": { 2134 | "node": ">=8" 2135 | } 2136 | }, 2137 | "node_modules/string-width-cjs/node_modules/emoji-regex": { 2138 | "version": "8.0.0", 2139 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 2140 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 2141 | "dev": true, 2142 | "license": "MIT" 2143 | }, 2144 | "node_modules/string-width-cjs/node_modules/strip-ansi": { 2145 | "version": "6.0.1", 2146 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 2147 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 2148 | "dev": true, 2149 | "license": "MIT", 2150 | "dependencies": { 2151 | "ansi-regex": "^5.0.1" 2152 | }, 2153 | "engines": { 2154 | "node": ">=8" 2155 | } 2156 | }, 2157 | "node_modules/strip-ansi": { 2158 | "version": "7.1.0", 2159 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", 2160 | "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", 2161 | "dev": true, 2162 | "license": "MIT", 2163 | "dependencies": { 2164 | "ansi-regex": "^6.0.1" 2165 | }, 2166 | "engines": { 2167 | "node": ">=12" 2168 | }, 2169 | "funding": { 2170 | "url": "https://github.com/chalk/strip-ansi?sponsor=1" 2171 | } 2172 | }, 2173 | "node_modules/strip-ansi-cjs": { 2174 | "name": "strip-ansi", 2175 | "version": "6.0.1", 2176 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 2177 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 2178 | "dev": true, 2179 | "license": "MIT", 2180 | "dependencies": { 2181 | "ansi-regex": "^5.0.1" 2182 | }, 2183 | "engines": { 2184 | "node": ">=8" 2185 | } 2186 | }, 2187 | "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { 2188 | "version": "5.0.1", 2189 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 2190 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 2191 | "dev": true, 2192 | "license": "MIT", 2193 | "engines": { 2194 | "node": ">=8" 2195 | } 2196 | }, 2197 | "node_modules/strip-json-comments": { 2198 | "version": "3.1.1", 2199 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 2200 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 2201 | "dev": true, 2202 | "engines": { 2203 | "node": ">=8" 2204 | }, 2205 | "funding": { 2206 | "url": "https://github.com/sponsors/sindresorhus" 2207 | } 2208 | }, 2209 | "node_modules/synckit": { 2210 | "version": "0.9.2", 2211 | "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz", 2212 | "integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==", 2213 | "dev": true, 2214 | "license": "MIT", 2215 | "dependencies": { 2216 | "@pkgr/core": "^0.1.0", 2217 | "tslib": "^2.6.2" 2218 | }, 2219 | "engines": { 2220 | "node": "^14.18.0 || >=16.0.0" 2221 | }, 2222 | "funding": { 2223 | "url": "https://opencollective.com/unts" 2224 | } 2225 | }, 2226 | "node_modules/to-regex-range": { 2227 | "version": "5.0.1", 2228 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 2229 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 2230 | "dev": true, 2231 | "license": "MIT", 2232 | "dependencies": { 2233 | "is-number": "^7.0.0" 2234 | }, 2235 | "engines": { 2236 | "node": ">=8.0" 2237 | } 2238 | }, 2239 | "node_modules/tslib": { 2240 | "version": "2.8.1", 2241 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", 2242 | "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", 2243 | "dev": true, 2244 | "license": "0BSD" 2245 | }, 2246 | "node_modules/type-check": { 2247 | "version": "0.4.0", 2248 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", 2249 | "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", 2250 | "dev": true, 2251 | "license": "MIT", 2252 | "dependencies": { 2253 | "prelude-ls": "^1.2.1" 2254 | }, 2255 | "engines": { 2256 | "node": ">= 0.8.0" 2257 | } 2258 | }, 2259 | "node_modules/uri-js": { 2260 | "version": "4.4.1", 2261 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 2262 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 2263 | "dev": true, 2264 | "license": "BSD-2-Clause", 2265 | "dependencies": { 2266 | "punycode": "^2.1.0" 2267 | } 2268 | }, 2269 | "node_modules/which": { 2270 | "version": "2.0.2", 2271 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 2272 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 2273 | "dev": true, 2274 | "license": "ISC", 2275 | "dependencies": { 2276 | "isexe": "^2.0.0" 2277 | }, 2278 | "bin": { 2279 | "node-which": "bin/node-which" 2280 | }, 2281 | "engines": { 2282 | "node": ">= 8" 2283 | } 2284 | }, 2285 | "node_modules/word-wrap": { 2286 | "version": "1.2.5", 2287 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", 2288 | "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", 2289 | "dev": true, 2290 | "license": "MIT", 2291 | "engines": { 2292 | "node": ">=0.10.0" 2293 | } 2294 | }, 2295 | "node_modules/workerpool": { 2296 | "version": "6.5.1", 2297 | "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", 2298 | "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", 2299 | "dev": true, 2300 | "license": "Apache-2.0" 2301 | }, 2302 | "node_modules/wrap-ansi": { 2303 | "version": "8.1.0", 2304 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", 2305 | "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", 2306 | "dev": true, 2307 | "license": "MIT", 2308 | "dependencies": { 2309 | "ansi-styles": "^6.1.0", 2310 | "string-width": "^5.0.1", 2311 | "strip-ansi": "^7.0.1" 2312 | }, 2313 | "engines": { 2314 | "node": ">=12" 2315 | }, 2316 | "funding": { 2317 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 2318 | } 2319 | }, 2320 | "node_modules/wrap-ansi-cjs": { 2321 | "name": "wrap-ansi", 2322 | "version": "7.0.0", 2323 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 2324 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 2325 | "dev": true, 2326 | "license": "MIT", 2327 | "dependencies": { 2328 | "ansi-styles": "^4.0.0", 2329 | "string-width": "^4.1.0", 2330 | "strip-ansi": "^6.0.0" 2331 | }, 2332 | "engines": { 2333 | "node": ">=10" 2334 | }, 2335 | "funding": { 2336 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 2337 | } 2338 | }, 2339 | "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { 2340 | "version": "5.0.1", 2341 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 2342 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 2343 | "dev": true, 2344 | "license": "MIT", 2345 | "engines": { 2346 | "node": ">=8" 2347 | } 2348 | }, 2349 | "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { 2350 | "version": "4.3.0", 2351 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 2352 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 2353 | "dev": true, 2354 | "license": "MIT", 2355 | "dependencies": { 2356 | "color-convert": "^2.0.1" 2357 | }, 2358 | "engines": { 2359 | "node": ">=8" 2360 | }, 2361 | "funding": { 2362 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 2363 | } 2364 | }, 2365 | "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { 2366 | "version": "8.0.0", 2367 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 2368 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 2369 | "dev": true, 2370 | "license": "MIT" 2371 | }, 2372 | "node_modules/wrap-ansi-cjs/node_modules/string-width": { 2373 | "version": "4.2.3", 2374 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 2375 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 2376 | "dev": true, 2377 | "license": "MIT", 2378 | "dependencies": { 2379 | "emoji-regex": "^8.0.0", 2380 | "is-fullwidth-code-point": "^3.0.0", 2381 | "strip-ansi": "^6.0.1" 2382 | }, 2383 | "engines": { 2384 | "node": ">=8" 2385 | } 2386 | }, 2387 | "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { 2388 | "version": "6.0.1", 2389 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 2390 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 2391 | "dev": true, 2392 | "license": "MIT", 2393 | "dependencies": { 2394 | "ansi-regex": "^5.0.1" 2395 | }, 2396 | "engines": { 2397 | "node": ">=8" 2398 | } 2399 | }, 2400 | "node_modules/y18n": { 2401 | "version": "5.0.8", 2402 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", 2403 | "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", 2404 | "dev": true, 2405 | "license": "ISC", 2406 | "engines": { 2407 | "node": ">=10" 2408 | } 2409 | }, 2410 | "node_modules/yargs": { 2411 | "version": "17.7.2", 2412 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", 2413 | "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", 2414 | "dev": true, 2415 | "license": "MIT", 2416 | "dependencies": { 2417 | "cliui": "^8.0.1", 2418 | "escalade": "^3.1.1", 2419 | "get-caller-file": "^2.0.5", 2420 | "require-directory": "^2.1.1", 2421 | "string-width": "^4.2.3", 2422 | "y18n": "^5.0.5", 2423 | "yargs-parser": "^21.1.1" 2424 | }, 2425 | "engines": { 2426 | "node": ">=12" 2427 | } 2428 | }, 2429 | "node_modules/yargs-parser": { 2430 | "version": "21.1.1", 2431 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", 2432 | "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", 2433 | "dev": true, 2434 | "license": "ISC", 2435 | "engines": { 2436 | "node": ">=12" 2437 | } 2438 | }, 2439 | "node_modules/yargs-unparser": { 2440 | "version": "2.0.0", 2441 | "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", 2442 | "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", 2443 | "dev": true, 2444 | "dependencies": { 2445 | "camelcase": "^6.0.0", 2446 | "decamelize": "^4.0.0", 2447 | "flat": "^5.0.2", 2448 | "is-plain-obj": "^2.1.0" 2449 | }, 2450 | "engines": { 2451 | "node": ">=10" 2452 | } 2453 | }, 2454 | "node_modules/yargs/node_modules/ansi-regex": { 2455 | "version": "5.0.1", 2456 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 2457 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 2458 | "dev": true, 2459 | "license": "MIT", 2460 | "engines": { 2461 | "node": ">=8" 2462 | } 2463 | }, 2464 | "node_modules/yargs/node_modules/emoji-regex": { 2465 | "version": "8.0.0", 2466 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 2467 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 2468 | "dev": true, 2469 | "license": "MIT" 2470 | }, 2471 | "node_modules/yargs/node_modules/string-width": { 2472 | "version": "4.2.3", 2473 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 2474 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 2475 | "dev": true, 2476 | "license": "MIT", 2477 | "dependencies": { 2478 | "emoji-regex": "^8.0.0", 2479 | "is-fullwidth-code-point": "^3.0.0", 2480 | "strip-ansi": "^6.0.1" 2481 | }, 2482 | "engines": { 2483 | "node": ">=8" 2484 | } 2485 | }, 2486 | "node_modules/yargs/node_modules/strip-ansi": { 2487 | "version": "6.0.1", 2488 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 2489 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 2490 | "dev": true, 2491 | "license": "MIT", 2492 | "dependencies": { 2493 | "ansi-regex": "^5.0.1" 2494 | }, 2495 | "engines": { 2496 | "node": ">=8" 2497 | } 2498 | }, 2499 | "node_modules/yocto-queue": { 2500 | "version": "0.1.0", 2501 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 2502 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 2503 | "dev": true, 2504 | "engines": { 2505 | "node": ">=10" 2506 | }, 2507 | "funding": { 2508 | "url": "https://github.com/sponsors/sindresorhus" 2509 | } 2510 | } 2511 | } 2512 | } 2513 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "MMM-ModuleScheduler", 3 | "version": "1.5.1", 4 | "description": "A MagicMirror helper module to schedule when modules should be shown, hidden or dimmed and when notifications should be sent.", 5 | "main": "MMM-ModuleScheduler.js", 6 | "scripts": { 7 | "test": "npm run test:unit && npm run test:prettier && npm run test:js", 8 | "test:unit": "NODE_ENV=test mocha tests --recursive", 9 | "test:prettier": "prettier --check **/*.{js,css,json,md,yml}", 10 | "test:js": "eslint *.js tests/**/*.js --config .eslint.config.js", 11 | "lint:prettier": "prettier --write **/*.{js,css,json,md,yml}", 12 | "lint:js": "eslint *.js tests/**/*.js --config .eslint.config.js --fix" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/ianperrin/MMM-ModuleScheduler.git" 17 | }, 18 | "keywords": [ 19 | "MagicMirror", 20 | "Module", 21 | "Scheduler" 22 | ], 23 | "author": "Ian Perrin", 24 | "license": "MIT", 25 | "bugs": { 26 | "url": "https://github.com/ianperrin/MMM-ModuleScheduler/issues" 27 | }, 28 | "homepage": "https://github.com/ianperrin/MMM-ModuleScheduler#readme", 29 | "devDependencies": { 30 | "chai": "^5.2.0", 31 | "eslint": "^9.24.0", 32 | "eslint-config-prettier": "^10.1.2", 33 | "eslint-plugin-jsdoc": "^50.6.9", 34 | "eslint-plugin-prettier": "^5.2.6", 35 | "mocha": "^11.1.0", 36 | "module-alias": "^2.2.3", 37 | "prettier": "^3.5.3" 38 | }, 39 | "dependencies": { 40 | "cron": "^4.3.0" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/node_helper.test.js: -------------------------------------------------------------------------------- 1 | const expect = require("chai").expect; 2 | const moduleAlias = require("module-alias"); 3 | moduleAlias.addAliases({ node_helper: "../../js/node_helper.js", logger: "../js/logger.js" }); 4 | var Module = require("../node_helper.js"); 5 | var helper = new Module(); 6 | helper.setName("MMM-ModuleScheduler"); 7 | 8 | describe("Functions in node_helper.js", function () { 9 | describe("getOrMakeArray", function () { 10 | it(`for a string should return an array`, function () { 11 | expect(helper.getOrMakeArray("dsg")).to.eql(["dsg"]); 12 | }); 13 | it(`for an array should return an array`, function () { 14 | expect(helper.getOrMakeArray(["dsg"])).to.eql(["dsg"]); 15 | }); 16 | it(`for a multiple value array should return an array`, function () { 17 | expect(helper.getOrMakeArray(["dsg", "sss"])).to.eql(["dsg", "sss"]); 18 | }); 19 | }); 20 | describe("isValidSchedule", function () { 21 | ["global", "group", "module"].forEach((scheduleType) => { 22 | const validSchedules = { 23 | "from-to": { from: "0 5 * * *", to: "0 9 * * *" } 24 | }; 25 | describe(`for '${scheduleType}' valid schedules`, function () { 26 | Object.keys(validSchedules).forEach((schedule) => { 27 | it(`for '${schedule}' should return true`, function () { 28 | expect(helper.isValidSchedule(validSchedules[schedule], scheduleType)).to.be.true; 29 | }); 30 | }); 31 | }); 32 | }); 33 | ["notification"].forEach((scheduleType) => { 34 | const validSchedules = { 35 | "from-to": { schedule: "0 5 * * *", notification: "TEST" } 36 | }; 37 | describe(`for '${scheduleType}' valid schedules`, function () { 38 | Object.keys(validSchedules).forEach((schedule) => { 39 | it(`for '${schedule}' should return true`, function () { 40 | expect(helper.isValidSchedule(validSchedules[schedule], scheduleType)).to.be.true; 41 | }); 42 | }); 43 | }); 44 | }); 45 | const invalidSchedules = { 46 | "from-hide": { from: "0 5 * * *", hide: "0 9 * * *" }, 47 | "show-to": { show: "0 5 * * *", to: "0 9 * * *" }, 48 | "show-hide": { show: "0 5 * * *", hide: "0 9 * * *" }, 49 | "schedule-id": { schedule: "0 5 * * *", id: "TEST" }, 50 | "from-notification": { from: "0 5 * * *", notification: "TEST" }, 51 | "from-id": { from: "0 5 * * *", id: "TEST" }, 52 | empty: {} 53 | }; 54 | ["global", "group", "module", "notification"].forEach((scheduleType) => { 55 | describe(`for '${scheduleType}' invalid schedules`, function () { 56 | Object.keys(invalidSchedules).forEach((schedule) => { 57 | it(`for '${schedule}' should return false`, function () { 58 | expect(helper.isValidSchedule(invalidSchedules[schedule], scheduleType)).to.be.false; 59 | }); 60 | }); 61 | }); 62 | }); 63 | }); 64 | describe("getRequiredPropertiesForType", function () { 65 | const scheduleTypeProps = { 66 | global: ["from", "to"], 67 | group: ["from", "to"], 68 | module: ["from", "to"], 69 | notification: ["schedule", "notification"] 70 | }; 71 | Object.keys(scheduleTypeProps).forEach((scheduleTypeProp) => { 72 | it(`for '${scheduleTypeProp}' should return '${scheduleTypeProps[scheduleTypeProp]}'`, function () { 73 | expect(helper.getRequiredPropertiesForType(scheduleTypeProp)).to.eql(scheduleTypeProps[scheduleTypeProp]); 74 | }); 75 | }); 76 | }); 77 | describe("isValidAction", function () { 78 | const actions = { 79 | show: true, 80 | hide: true, 81 | dim: true, 82 | send: true, 83 | "anything else": false 84 | }; 85 | Object.keys(actions).forEach((action) => { 86 | it(`for '${action}' should return '${actions[action]}'`, function () { 87 | expect(helper.isValidAction(action)).to.eql(actions[action]); 88 | }); 89 | }); 90 | }); 91 | }); 92 | --------------------------------------------------------------------------------