Procedurally generates a radio weather report

tests for weather class

+816
package-lock.json
··· 14 }, 15 "devDependencies": { 16 "@types/node": "24.3.0", 17 "typescript": "5.9.2", 18 "vitest": "3.2.4" 19 } 20 }, 21 "node_modules/@esbuild/aix-ppc64": { ··· 460 "node": ">=18" 461 } 462 }, 463 "node_modules/@jridgewell/sourcemap-codec": { 464 "version": "1.5.5", 465 "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", 466 "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", 467 "dev": true, 468 "license": "MIT" 469 }, 470 "node_modules/@rollup/rollup-android-arm-eabi": { 471 "version": "4.48.0", ··· 781 "undici-types": "~7.10.0" 782 } 783 }, 784 "node_modules/@vitest/expect": { 785 "version": "3.2.4", 786 "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", ··· 896 "url": "https://opencollective.com/vitest" 897 } 898 }, 899 "node_modules/assertion-error": { 900 "version": "2.0.1", 901 "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", ··· 906 "node": ">=12" 907 } 908 }, 909 "node_modules/cac": { 910 "version": "6.7.14", 911 "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", ··· 943 "node": ">= 16" 944 } 945 }, 946 "node_modules/debug": { 947 "version": "4.4.1", 948 "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", ··· 971 "node": ">=6" 972 } 973 }, 974 "node_modules/es-module-lexer": { 975 "version": "1.7.0", 976 "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", ··· 1058 } 1059 } 1060 }, 1061 "node_modules/fsevents": { 1062 "version": "2.3.3", 1063 "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", ··· 1073 "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 1074 } 1075 }, 1076 "node_modules/js-tokens": { 1077 "version": "9.0.1", 1078 "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", ··· 1099 "dev": true, 1100 "license": "MIT" 1101 }, 1102 "node_modules/magic-string": { 1103 "version": "0.30.18", 1104 "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.18.tgz", ··· 1109 "@jridgewell/sourcemap-codec": "^1.5.5" 1110 } 1111 }, 1112 "node_modules/ms": { 1113 "version": "2.1.3", 1114 "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", ··· 1164 "node-fetch": "^2.6.0" 1165 } 1166 }, 1167 "node_modules/pathe": { 1168 "version": "2.0.3", 1169 "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", ··· 1270 "fsevents": "~2.3.2" 1271 } 1272 }, 1273 "node_modules/siginfo": { 1274 "version": "2.0.0", 1275 "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", ··· 1277 "dev": true, 1278 "license": "ISC" 1279 }, 1280 "node_modules/source-map-js": { 1281 "version": "1.2.1", 1282 "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", ··· 1301 "dev": true, 1302 "license": "MIT" 1303 }, 1304 "node_modules/strip-literal": { 1305 "version": "3.0.0", 1306 "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.0.0.tgz", ··· 1312 }, 1313 "funding": { 1314 "url": "https://github.com/sponsors/antfu" 1315 } 1316 }, 1317 "node_modules/tinybench": { ··· 1589 "webidl-conversions": "^3.0.0" 1590 } 1591 }, 1592 "node_modules/why-is-node-running": { 1593 "version": "2.3.0", 1594 "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", ··· 1601 }, 1602 "bin": { 1603 "why-is-node-running": "cli.js" 1604 }, 1605 "engines": { 1606 "node": ">=8"
··· 14 }, 15 "devDependencies": { 16 "@types/node": "24.3.0", 17 + "@vitest/coverage-v8": "3.2.4", 18 "typescript": "5.9.2", 19 "vitest": "3.2.4" 20 + } 21 + }, 22 + "node_modules/@ampproject/remapping": { 23 + "version": "2.3.0", 24 + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", 25 + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", 26 + "dev": true, 27 + "license": "Apache-2.0", 28 + "dependencies": { 29 + "@jridgewell/gen-mapping": "^0.3.5", 30 + "@jridgewell/trace-mapping": "^0.3.24" 31 + }, 32 + "engines": { 33 + "node": ">=6.0.0" 34 + } 35 + }, 36 + "node_modules/@babel/helper-string-parser": { 37 + "version": "7.27.1", 38 + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", 39 + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", 40 + "dev": true, 41 + "license": "MIT", 42 + "engines": { 43 + "node": ">=6.9.0" 44 + } 45 + }, 46 + "node_modules/@babel/helper-validator-identifier": { 47 + "version": "7.27.1", 48 + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", 49 + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", 50 + "dev": true, 51 + "license": "MIT", 52 + "engines": { 53 + "node": ">=6.9.0" 54 + } 55 + }, 56 + "node_modules/@babel/parser": { 57 + "version": "7.28.3", 58 + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.3.tgz", 59 + "integrity": "sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==", 60 + "dev": true, 61 + "license": "MIT", 62 + "dependencies": { 63 + "@babel/types": "^7.28.2" 64 + }, 65 + "bin": { 66 + "parser": "bin/babel-parser.js" 67 + }, 68 + "engines": { 69 + "node": ">=6.0.0" 70 + } 71 + }, 72 + "node_modules/@babel/types": { 73 + "version": "7.28.2", 74 + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz", 75 + "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==", 76 + "dev": true, 77 + "license": "MIT", 78 + "dependencies": { 79 + "@babel/helper-string-parser": "^7.27.1", 80 + "@babel/helper-validator-identifier": "^7.27.1" 81 + }, 82 + "engines": { 83 + "node": ">=6.9.0" 84 + } 85 + }, 86 + "node_modules/@bcoe/v8-coverage": { 87 + "version": "1.0.2", 88 + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", 89 + "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", 90 + "dev": true, 91 + "license": "MIT", 92 + "engines": { 93 + "node": ">=18" 94 } 95 }, 96 "node_modules/@esbuild/aix-ppc64": { ··· 535 "node": ">=18" 536 } 537 }, 538 + "node_modules/@isaacs/cliui": { 539 + "version": "8.0.2", 540 + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", 541 + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", 542 + "dev": true, 543 + "license": "ISC", 544 + "dependencies": { 545 + "string-width": "^5.1.2", 546 + "string-width-cjs": "npm:string-width@^4.2.0", 547 + "strip-ansi": "^7.0.1", 548 + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", 549 + "wrap-ansi": "^8.1.0", 550 + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" 551 + }, 552 + "engines": { 553 + "node": ">=12" 554 + } 555 + }, 556 + "node_modules/@istanbuljs/schema": { 557 + "version": "0.1.3", 558 + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", 559 + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", 560 + "dev": true, 561 + "license": "MIT", 562 + "engines": { 563 + "node": ">=8" 564 + } 565 + }, 566 + "node_modules/@jridgewell/gen-mapping": { 567 + "version": "0.3.13", 568 + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", 569 + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", 570 + "dev": true, 571 + "license": "MIT", 572 + "dependencies": { 573 + "@jridgewell/sourcemap-codec": "^1.5.0", 574 + "@jridgewell/trace-mapping": "^0.3.24" 575 + } 576 + }, 577 + "node_modules/@jridgewell/resolve-uri": { 578 + "version": "3.1.2", 579 + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", 580 + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", 581 + "dev": true, 582 + "license": "MIT", 583 + "engines": { 584 + "node": ">=6.0.0" 585 + } 586 + }, 587 "node_modules/@jridgewell/sourcemap-codec": { 588 "version": "1.5.5", 589 "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", 590 "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", 591 "dev": true, 592 "license": "MIT" 593 + }, 594 + "node_modules/@jridgewell/trace-mapping": { 595 + "version": "0.3.30", 596 + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.30.tgz", 597 + "integrity": "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==", 598 + "dev": true, 599 + "license": "MIT", 600 + "dependencies": { 601 + "@jridgewell/resolve-uri": "^3.1.0", 602 + "@jridgewell/sourcemap-codec": "^1.4.14" 603 + } 604 + }, 605 + "node_modules/@pkgjs/parseargs": { 606 + "version": "0.11.0", 607 + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", 608 + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", 609 + "dev": true, 610 + "license": "MIT", 611 + "optional": true, 612 + "engines": { 613 + "node": ">=14" 614 + } 615 }, 616 "node_modules/@rollup/rollup-android-arm-eabi": { 617 "version": "4.48.0", ··· 927 "undici-types": "~7.10.0" 928 } 929 }, 930 + "node_modules/@vitest/coverage-v8": { 931 + "version": "3.2.4", 932 + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.2.4.tgz", 933 + "integrity": "sha512-EyF9SXU6kS5Ku/U82E259WSnvg6c8KTjppUncuNdm5QHpe17mwREHnjDzozC8x9MZ0xfBUFSaLkRv4TMA75ALQ==", 934 + "dev": true, 935 + "license": "MIT", 936 + "dependencies": { 937 + "@ampproject/remapping": "^2.3.0", 938 + "@bcoe/v8-coverage": "^1.0.2", 939 + "ast-v8-to-istanbul": "^0.3.3", 940 + "debug": "^4.4.1", 941 + "istanbul-lib-coverage": "^3.2.2", 942 + "istanbul-lib-report": "^3.0.1", 943 + "istanbul-lib-source-maps": "^5.0.6", 944 + "istanbul-reports": "^3.1.7", 945 + "magic-string": "^0.30.17", 946 + "magicast": "^0.3.5", 947 + "std-env": "^3.9.0", 948 + "test-exclude": "^7.0.1", 949 + "tinyrainbow": "^2.0.0" 950 + }, 951 + "funding": { 952 + "url": "https://opencollective.com/vitest" 953 + }, 954 + "peerDependencies": { 955 + "@vitest/browser": "3.2.4", 956 + "vitest": "3.2.4" 957 + }, 958 + "peerDependenciesMeta": { 959 + "@vitest/browser": { 960 + "optional": true 961 + } 962 + } 963 + }, 964 "node_modules/@vitest/expect": { 965 "version": "3.2.4", 966 "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", ··· 1076 "url": "https://opencollective.com/vitest" 1077 } 1078 }, 1079 + "node_modules/ansi-regex": { 1080 + "version": "6.2.0", 1081 + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.0.tgz", 1082 + "integrity": "sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg==", 1083 + "dev": true, 1084 + "license": "MIT", 1085 + "engines": { 1086 + "node": ">=12" 1087 + }, 1088 + "funding": { 1089 + "url": "https://github.com/chalk/ansi-regex?sponsor=1" 1090 + } 1091 + }, 1092 + "node_modules/ansi-styles": { 1093 + "version": "6.2.1", 1094 + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", 1095 + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", 1096 + "dev": true, 1097 + "license": "MIT", 1098 + "engines": { 1099 + "node": ">=12" 1100 + }, 1101 + "funding": { 1102 + "url": "https://github.com/chalk/ansi-styles?sponsor=1" 1103 + } 1104 + }, 1105 "node_modules/assertion-error": { 1106 "version": "2.0.1", 1107 "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", ··· 1112 "node": ">=12" 1113 } 1114 }, 1115 + "node_modules/ast-v8-to-istanbul": { 1116 + "version": "0.3.4", 1117 + "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.4.tgz", 1118 + "integrity": "sha512-cxrAnZNLBnQwBPByK4CeDaw5sWZtMilJE/Q3iDA0aamgaIVNDF9T6K2/8DfYDZEejZ2jNnDrG9m8MY72HFd0KA==", 1119 + "dev": true, 1120 + "license": "MIT", 1121 + "dependencies": { 1122 + "@jridgewell/trace-mapping": "^0.3.29", 1123 + "estree-walker": "^3.0.3", 1124 + "js-tokens": "^9.0.1" 1125 + } 1126 + }, 1127 + "node_modules/balanced-match": { 1128 + "version": "1.0.2", 1129 + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 1130 + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 1131 + "dev": true, 1132 + "license": "MIT" 1133 + }, 1134 + "node_modules/brace-expansion": { 1135 + "version": "2.0.2", 1136 + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", 1137 + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", 1138 + "dev": true, 1139 + "license": "MIT", 1140 + "dependencies": { 1141 + "balanced-match": "^1.0.0" 1142 + } 1143 + }, 1144 "node_modules/cac": { 1145 "version": "6.7.14", 1146 "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", ··· 1178 "node": ">= 16" 1179 } 1180 }, 1181 + "node_modules/color-convert": { 1182 + "version": "2.0.1", 1183 + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 1184 + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 1185 + "dev": true, 1186 + "license": "MIT", 1187 + "dependencies": { 1188 + "color-name": "~1.1.4" 1189 + }, 1190 + "engines": { 1191 + "node": ">=7.0.0" 1192 + } 1193 + }, 1194 + "node_modules/color-name": { 1195 + "version": "1.1.4", 1196 + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 1197 + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 1198 + "dev": true, 1199 + "license": "MIT" 1200 + }, 1201 + "node_modules/cross-spawn": { 1202 + "version": "7.0.6", 1203 + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", 1204 + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", 1205 + "dev": true, 1206 + "license": "MIT", 1207 + "dependencies": { 1208 + "path-key": "^3.1.0", 1209 + "shebang-command": "^2.0.0", 1210 + "which": "^2.0.1" 1211 + }, 1212 + "engines": { 1213 + "node": ">= 8" 1214 + } 1215 + }, 1216 "node_modules/debug": { 1217 "version": "4.4.1", 1218 "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", ··· 1241 "node": ">=6" 1242 } 1243 }, 1244 + "node_modules/eastasianwidth": { 1245 + "version": "0.2.0", 1246 + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", 1247 + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", 1248 + "dev": true, 1249 + "license": "MIT" 1250 + }, 1251 + "node_modules/emoji-regex": { 1252 + "version": "9.2.2", 1253 + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", 1254 + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", 1255 + "dev": true, 1256 + "license": "MIT" 1257 + }, 1258 "node_modules/es-module-lexer": { 1259 "version": "1.7.0", 1260 "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", ··· 1342 } 1343 } 1344 }, 1345 + "node_modules/foreground-child": { 1346 + "version": "3.3.1", 1347 + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", 1348 + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", 1349 + "dev": true, 1350 + "license": "ISC", 1351 + "dependencies": { 1352 + "cross-spawn": "^7.0.6", 1353 + "signal-exit": "^4.0.1" 1354 + }, 1355 + "engines": { 1356 + "node": ">=14" 1357 + }, 1358 + "funding": { 1359 + "url": "https://github.com/sponsors/isaacs" 1360 + } 1361 + }, 1362 "node_modules/fsevents": { 1363 "version": "2.3.3", 1364 "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", ··· 1374 "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 1375 } 1376 }, 1377 + "node_modules/glob": { 1378 + "version": "10.4.5", 1379 + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", 1380 + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", 1381 + "dev": true, 1382 + "license": "ISC", 1383 + "dependencies": { 1384 + "foreground-child": "^3.1.0", 1385 + "jackspeak": "^3.1.2", 1386 + "minimatch": "^9.0.4", 1387 + "minipass": "^7.1.2", 1388 + "package-json-from-dist": "^1.0.0", 1389 + "path-scurry": "^1.11.1" 1390 + }, 1391 + "bin": { 1392 + "glob": "dist/esm/bin.mjs" 1393 + }, 1394 + "funding": { 1395 + "url": "https://github.com/sponsors/isaacs" 1396 + } 1397 + }, 1398 + "node_modules/has-flag": { 1399 + "version": "4.0.0", 1400 + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 1401 + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 1402 + "dev": true, 1403 + "license": "MIT", 1404 + "engines": { 1405 + "node": ">=8" 1406 + } 1407 + }, 1408 + "node_modules/html-escaper": { 1409 + "version": "2.0.2", 1410 + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", 1411 + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", 1412 + "dev": true, 1413 + "license": "MIT" 1414 + }, 1415 + "node_modules/is-fullwidth-code-point": { 1416 + "version": "3.0.0", 1417 + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 1418 + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 1419 + "dev": true, 1420 + "license": "MIT", 1421 + "engines": { 1422 + "node": ">=8" 1423 + } 1424 + }, 1425 + "node_modules/isexe": { 1426 + "version": "2.0.0", 1427 + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 1428 + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 1429 + "dev": true, 1430 + "license": "ISC" 1431 + }, 1432 + "node_modules/istanbul-lib-coverage": { 1433 + "version": "3.2.2", 1434 + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", 1435 + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", 1436 + "dev": true, 1437 + "license": "BSD-3-Clause", 1438 + "engines": { 1439 + "node": ">=8" 1440 + } 1441 + }, 1442 + "node_modules/istanbul-lib-report": { 1443 + "version": "3.0.1", 1444 + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", 1445 + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", 1446 + "dev": true, 1447 + "license": "BSD-3-Clause", 1448 + "dependencies": { 1449 + "istanbul-lib-coverage": "^3.0.0", 1450 + "make-dir": "^4.0.0", 1451 + "supports-color": "^7.1.0" 1452 + }, 1453 + "engines": { 1454 + "node": ">=10" 1455 + } 1456 + }, 1457 + "node_modules/istanbul-lib-source-maps": { 1458 + "version": "5.0.6", 1459 + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", 1460 + "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", 1461 + "dev": true, 1462 + "license": "BSD-3-Clause", 1463 + "dependencies": { 1464 + "@jridgewell/trace-mapping": "^0.3.23", 1465 + "debug": "^4.1.1", 1466 + "istanbul-lib-coverage": "^3.0.0" 1467 + }, 1468 + "engines": { 1469 + "node": ">=10" 1470 + } 1471 + }, 1472 + "node_modules/istanbul-reports": { 1473 + "version": "3.2.0", 1474 + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", 1475 + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", 1476 + "dev": true, 1477 + "license": "BSD-3-Clause", 1478 + "dependencies": { 1479 + "html-escaper": "^2.0.0", 1480 + "istanbul-lib-report": "^3.0.0" 1481 + }, 1482 + "engines": { 1483 + "node": ">=8" 1484 + } 1485 + }, 1486 + "node_modules/jackspeak": { 1487 + "version": "3.4.3", 1488 + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", 1489 + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", 1490 + "dev": true, 1491 + "license": "BlueOak-1.0.0", 1492 + "dependencies": { 1493 + "@isaacs/cliui": "^8.0.2" 1494 + }, 1495 + "funding": { 1496 + "url": "https://github.com/sponsors/isaacs" 1497 + }, 1498 + "optionalDependencies": { 1499 + "@pkgjs/parseargs": "^0.11.0" 1500 + } 1501 + }, 1502 "node_modules/js-tokens": { 1503 "version": "9.0.1", 1504 "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", ··· 1525 "dev": true, 1526 "license": "MIT" 1527 }, 1528 + "node_modules/lru-cache": { 1529 + "version": "10.4.3", 1530 + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", 1531 + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", 1532 + "dev": true, 1533 + "license": "ISC" 1534 + }, 1535 "node_modules/magic-string": { 1536 "version": "0.30.18", 1537 "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.18.tgz", ··· 1542 "@jridgewell/sourcemap-codec": "^1.5.5" 1543 } 1544 }, 1545 + "node_modules/magicast": { 1546 + "version": "0.3.5", 1547 + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz", 1548 + "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==", 1549 + "dev": true, 1550 + "license": "MIT", 1551 + "dependencies": { 1552 + "@babel/parser": "^7.25.4", 1553 + "@babel/types": "^7.25.4", 1554 + "source-map-js": "^1.2.0" 1555 + } 1556 + }, 1557 + "node_modules/make-dir": { 1558 + "version": "4.0.0", 1559 + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", 1560 + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", 1561 + "dev": true, 1562 + "license": "MIT", 1563 + "dependencies": { 1564 + "semver": "^7.5.3" 1565 + }, 1566 + "engines": { 1567 + "node": ">=10" 1568 + }, 1569 + "funding": { 1570 + "url": "https://github.com/sponsors/sindresorhus" 1571 + } 1572 + }, 1573 + "node_modules/minimatch": { 1574 + "version": "9.0.5", 1575 + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", 1576 + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", 1577 + "dev": true, 1578 + "license": "ISC", 1579 + "dependencies": { 1580 + "brace-expansion": "^2.0.1" 1581 + }, 1582 + "engines": { 1583 + "node": ">=16 || 14 >=14.17" 1584 + }, 1585 + "funding": { 1586 + "url": "https://github.com/sponsors/isaacs" 1587 + } 1588 + }, 1589 + "node_modules/minipass": { 1590 + "version": "7.1.2", 1591 + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", 1592 + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", 1593 + "dev": true, 1594 + "license": "ISC", 1595 + "engines": { 1596 + "node": ">=16 || 14 >=14.17" 1597 + } 1598 + }, 1599 "node_modules/ms": { 1600 "version": "2.1.3", 1601 "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", ··· 1651 "node-fetch": "^2.6.0" 1652 } 1653 }, 1654 + "node_modules/package-json-from-dist": { 1655 + "version": "1.0.1", 1656 + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", 1657 + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", 1658 + "dev": true, 1659 + "license": "BlueOak-1.0.0" 1660 + }, 1661 + "node_modules/path-key": { 1662 + "version": "3.1.1", 1663 + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 1664 + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 1665 + "dev": true, 1666 + "license": "MIT", 1667 + "engines": { 1668 + "node": ">=8" 1669 + } 1670 + }, 1671 + "node_modules/path-scurry": { 1672 + "version": "1.11.1", 1673 + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", 1674 + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", 1675 + "dev": true, 1676 + "license": "BlueOak-1.0.0", 1677 + "dependencies": { 1678 + "lru-cache": "^10.2.0", 1679 + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" 1680 + }, 1681 + "engines": { 1682 + "node": ">=16 || 14 >=14.18" 1683 + }, 1684 + "funding": { 1685 + "url": "https://github.com/sponsors/isaacs" 1686 + } 1687 + }, 1688 "node_modules/pathe": { 1689 "version": "2.0.3", 1690 "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", ··· 1791 "fsevents": "~2.3.2" 1792 } 1793 }, 1794 + "node_modules/semver": { 1795 + "version": "7.7.2", 1796 + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", 1797 + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", 1798 + "dev": true, 1799 + "license": "ISC", 1800 + "bin": { 1801 + "semver": "bin/semver.js" 1802 + }, 1803 + "engines": { 1804 + "node": ">=10" 1805 + } 1806 + }, 1807 + "node_modules/shebang-command": { 1808 + "version": "2.0.0", 1809 + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 1810 + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 1811 + "dev": true, 1812 + "license": "MIT", 1813 + "dependencies": { 1814 + "shebang-regex": "^3.0.0" 1815 + }, 1816 + "engines": { 1817 + "node": ">=8" 1818 + } 1819 + }, 1820 + "node_modules/shebang-regex": { 1821 + "version": "3.0.0", 1822 + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 1823 + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 1824 + "dev": true, 1825 + "license": "MIT", 1826 + "engines": { 1827 + "node": ">=8" 1828 + } 1829 + }, 1830 "node_modules/siginfo": { 1831 "version": "2.0.0", 1832 "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", ··· 1834 "dev": true, 1835 "license": "ISC" 1836 }, 1837 + "node_modules/signal-exit": { 1838 + "version": "4.1.0", 1839 + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", 1840 + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", 1841 + "dev": true, 1842 + "license": "ISC", 1843 + "engines": { 1844 + "node": ">=14" 1845 + }, 1846 + "funding": { 1847 + "url": "https://github.com/sponsors/isaacs" 1848 + } 1849 + }, 1850 "node_modules/source-map-js": { 1851 "version": "1.2.1", 1852 "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", ··· 1871 "dev": true, 1872 "license": "MIT" 1873 }, 1874 + "node_modules/string-width": { 1875 + "version": "5.1.2", 1876 + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", 1877 + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", 1878 + "dev": true, 1879 + "license": "MIT", 1880 + "dependencies": { 1881 + "eastasianwidth": "^0.2.0", 1882 + "emoji-regex": "^9.2.2", 1883 + "strip-ansi": "^7.0.1" 1884 + }, 1885 + "engines": { 1886 + "node": ">=12" 1887 + }, 1888 + "funding": { 1889 + "url": "https://github.com/sponsors/sindresorhus" 1890 + } 1891 + }, 1892 + "node_modules/string-width-cjs": { 1893 + "name": "string-width", 1894 + "version": "4.2.3", 1895 + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 1896 + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 1897 + "dev": true, 1898 + "license": "MIT", 1899 + "dependencies": { 1900 + "emoji-regex": "^8.0.0", 1901 + "is-fullwidth-code-point": "^3.0.0", 1902 + "strip-ansi": "^6.0.1" 1903 + }, 1904 + "engines": { 1905 + "node": ">=8" 1906 + } 1907 + }, 1908 + "node_modules/string-width-cjs/node_modules/ansi-regex": { 1909 + "version": "5.0.1", 1910 + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 1911 + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 1912 + "dev": true, 1913 + "license": "MIT", 1914 + "engines": { 1915 + "node": ">=8" 1916 + } 1917 + }, 1918 + "node_modules/string-width-cjs/node_modules/emoji-regex": { 1919 + "version": "8.0.0", 1920 + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 1921 + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 1922 + "dev": true, 1923 + "license": "MIT" 1924 + }, 1925 + "node_modules/string-width-cjs/node_modules/strip-ansi": { 1926 + "version": "6.0.1", 1927 + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 1928 + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 1929 + "dev": true, 1930 + "license": "MIT", 1931 + "dependencies": { 1932 + "ansi-regex": "^5.0.1" 1933 + }, 1934 + "engines": { 1935 + "node": ">=8" 1936 + } 1937 + }, 1938 + "node_modules/strip-ansi": { 1939 + "version": "7.1.0", 1940 + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", 1941 + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", 1942 + "dev": true, 1943 + "license": "MIT", 1944 + "dependencies": { 1945 + "ansi-regex": "^6.0.1" 1946 + }, 1947 + "engines": { 1948 + "node": ">=12" 1949 + }, 1950 + "funding": { 1951 + "url": "https://github.com/chalk/strip-ansi?sponsor=1" 1952 + } 1953 + }, 1954 + "node_modules/strip-ansi-cjs": { 1955 + "name": "strip-ansi", 1956 + "version": "6.0.1", 1957 + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 1958 + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 1959 + "dev": true, 1960 + "license": "MIT", 1961 + "dependencies": { 1962 + "ansi-regex": "^5.0.1" 1963 + }, 1964 + "engines": { 1965 + "node": ">=8" 1966 + } 1967 + }, 1968 + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { 1969 + "version": "5.0.1", 1970 + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 1971 + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 1972 + "dev": true, 1973 + "license": "MIT", 1974 + "engines": { 1975 + "node": ">=8" 1976 + } 1977 + }, 1978 "node_modules/strip-literal": { 1979 "version": "3.0.0", 1980 "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.0.0.tgz", ··· 1986 }, 1987 "funding": { 1988 "url": "https://github.com/sponsors/antfu" 1989 + } 1990 + }, 1991 + "node_modules/supports-color": { 1992 + "version": "7.2.0", 1993 + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 1994 + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 1995 + "dev": true, 1996 + "license": "MIT", 1997 + "dependencies": { 1998 + "has-flag": "^4.0.0" 1999 + }, 2000 + "engines": { 2001 + "node": ">=8" 2002 + } 2003 + }, 2004 + "node_modules/test-exclude": { 2005 + "version": "7.0.1", 2006 + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz", 2007 + "integrity": "sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==", 2008 + "dev": true, 2009 + "license": "ISC", 2010 + "dependencies": { 2011 + "@istanbuljs/schema": "^0.1.2", 2012 + "glob": "^10.4.1", 2013 + "minimatch": "^9.0.4" 2014 + }, 2015 + "engines": { 2016 + "node": ">=18" 2017 } 2018 }, 2019 "node_modules/tinybench": { ··· 2291 "webidl-conversions": "^3.0.0" 2292 } 2293 }, 2294 + "node_modules/which": { 2295 + "version": "2.0.2", 2296 + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 2297 + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 2298 + "dev": true, 2299 + "license": "ISC", 2300 + "dependencies": { 2301 + "isexe": "^2.0.0" 2302 + }, 2303 + "bin": { 2304 + "node-which": "bin/node-which" 2305 + }, 2306 + "engines": { 2307 + "node": ">= 8" 2308 + } 2309 + }, 2310 "node_modules/why-is-node-running": { 2311 "version": "2.3.0", 2312 "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", ··· 2319 }, 2320 "bin": { 2321 "why-is-node-running": "cli.js" 2322 + }, 2323 + "engines": { 2324 + "node": ">=8" 2325 + } 2326 + }, 2327 + "node_modules/wrap-ansi": { 2328 + "version": "8.1.0", 2329 + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", 2330 + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", 2331 + "dev": true, 2332 + "license": "MIT", 2333 + "dependencies": { 2334 + "ansi-styles": "^6.1.0", 2335 + "string-width": "^5.0.1", 2336 + "strip-ansi": "^7.0.1" 2337 + }, 2338 + "engines": { 2339 + "node": ">=12" 2340 + }, 2341 + "funding": { 2342 + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 2343 + } 2344 + }, 2345 + "node_modules/wrap-ansi-cjs": { 2346 + "name": "wrap-ansi", 2347 + "version": "7.0.0", 2348 + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 2349 + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 2350 + "dev": true, 2351 + "license": "MIT", 2352 + "dependencies": { 2353 + "ansi-styles": "^4.0.0", 2354 + "string-width": "^4.1.0", 2355 + "strip-ansi": "^6.0.0" 2356 + }, 2357 + "engines": { 2358 + "node": ">=10" 2359 + }, 2360 + "funding": { 2361 + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 2362 + } 2363 + }, 2364 + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { 2365 + "version": "5.0.1", 2366 + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 2367 + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 2368 + "dev": true, 2369 + "license": "MIT", 2370 + "engines": { 2371 + "node": ">=8" 2372 + } 2373 + }, 2374 + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { 2375 + "version": "4.3.0", 2376 + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 2377 + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 2378 + "dev": true, 2379 + "license": "MIT", 2380 + "dependencies": { 2381 + "color-convert": "^2.0.1" 2382 + }, 2383 + "engines": { 2384 + "node": ">=8" 2385 + }, 2386 + "funding": { 2387 + "url": "https://github.com/chalk/ansi-styles?sponsor=1" 2388 + } 2389 + }, 2390 + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { 2391 + "version": "8.0.0", 2392 + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 2393 + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 2394 + "dev": true, 2395 + "license": "MIT" 2396 + }, 2397 + "node_modules/wrap-ansi-cjs/node_modules/string-width": { 2398 + "version": "4.2.3", 2399 + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 2400 + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 2401 + "dev": true, 2402 + "license": "MIT", 2403 + "dependencies": { 2404 + "emoji-regex": "^8.0.0", 2405 + "is-fullwidth-code-point": "^3.0.0", 2406 + "strip-ansi": "^6.0.1" 2407 + }, 2408 + "engines": { 2409 + "node": ">=8" 2410 + } 2411 + }, 2412 + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { 2413 + "version": "6.0.1", 2414 + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 2415 + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 2416 + "dev": true, 2417 + "license": "MIT", 2418 + "dependencies": { 2419 + "ansi-regex": "^5.0.1" 2420 }, 2421 "engines": { 2422 "node": ">=8"
+2 -1
package.json
··· 31 "devDependencies": { 32 "typescript": "5.9.2", 33 "@types/node": "24.3.0", 34 - "vitest": "3.2.4" 35 } 36 }
··· 31 "devDependencies": { 32 "typescript": "5.9.2", 33 "@types/node": "24.3.0", 34 + "vitest": "3.2.4", 35 + "@vitest/coverage-v8": "3.2.4" 36 } 37 }
-3
src/voice.ts
··· 130 const tokens: string[] = []; 131 const numGroups = str.split(','); 132 const seperators = [LINES.TRILLION, LINES.BILLION, LINES.MILLION, LINES.THOUSAND]; 133 - if (numGroups.length > 5) { 134 - return digitByDigit(str); 135 - } 136 seperators.splice(0, seperators.length - numGroups.length + 1); 137 numGroups.forEach(g => { 138 if (g !== '000') {
··· 130 const tokens: string[] = []; 131 const numGroups = str.split(','); 132 const seperators = [LINES.TRILLION, LINES.BILLION, LINES.MILLION, LINES.THOUSAND]; 133 seperators.splice(0, seperators.length - numGroups.length + 1); 134 numGroups.forEach(g => { 135 if (g !== '000') {
+1 -1
src/weather.ts
··· 98 99 export default Weather; 100 export { Weather }; 101 - export type { WeatherConfig, CityName };
··· 98 99 export default Weather; 100 export { Weather }; 101 + export type { WeatherConfig, CityName, CurrentResponse, ThreeHourResponse };
+14 -1
test/voice.test.ts
··· 1 - import { assert, describe, expect, it } from 'vitest' 2 import { voiceLines, LINES } from '../src/voice.js'; 3 import type { Voice } from '../src/voice.js'; 4 ··· 112 expect(voiceLines(dummyVoice, -Infinity)).length.to.be.empty; 113 expect(voiceLines(dummyVoice, NaN)).length.to.be.empty; 114 expect(voiceLines(dummyVoice, 1e21)).length.to.be.empty; 115 }); 116 });
··· 1 + import path from 'path'; 2 + import { describe, expect, it } from 'vitest'; 3 import { voiceLines, LINES } from '../src/voice.js'; 4 import type { Voice } from '../src/voice.js'; 5 ··· 113 expect(voiceLines(dummyVoice, -Infinity)).length.to.be.empty; 114 expect(voiceLines(dummyVoice, NaN)).length.to.be.empty; 115 expect(voiceLines(dummyVoice, 1e21)).length.to.be.empty; 116 + }); 117 + 118 + it('returns the results as paths when voice configuration is provided', () => { 119 + const directory = path.join('audio', 'voice', 'someone'); 120 + const v: Voice = { 121 + directory, 122 + extension: 'flac' 123 + } 124 + expect(voiceLines(v, 29)).to.include.ordered.members([ 125 + path.join(directory, `twenty.flac`), 126 + path.join(directory, `nine.flac`), 127 + ]); 128 }); 129 });
+338
test/weather.test.ts
···
··· 1 + import OpenWeatherMap from 'openweathermap-ts'; 2 + import { describe, expect, it, vi, beforeEach, type Mocked } from 'vitest'; 3 + import { Weather } from '../src/weather.js'; 4 + import type { CurrentResponse, ThreeHourResponse } from '../src/weather.js'; 5 + 6 + // #region mock API responses 7 + const current: CurrentResponse = { 8 + "coord": { 9 + "lon": 7.367, 10 + "lat": 45.133 11 + }, 12 + "weather": [ 13 + { 14 + "id": 501, 15 + "main": "Rain", 16 + "description": "moderate rain", 17 + "icon": "10d" 18 + } 19 + ], 20 + "base": "stations", 21 + "main": { 22 + "temp": 284.2, 23 + "feels_like": 282.93, 24 + "temp_min": 283.06, 25 + "temp_max": 286.82, 26 + "pressure": 1021, 27 + "humidity": 60, 28 + "sea_level": 1021, 29 + "grnd_level": 910 30 + }, 31 + "visibility": 10000, 32 + "wind": { 33 + "speed": 4.09, 34 + "deg": 121, 35 + "gust": 3.47 36 + }, 37 + "rain": { 38 + "1h": 2.73 39 + }, 40 + "clouds": { 41 + "all": 83 42 + }, 43 + "dt": 1726660758, 44 + "sys": { 45 + "type": 1, 46 + "id": 6736, 47 + "country": "IT", 48 + "sunrise": 1726636384, 49 + "sunset": 1726680975 50 + }, 51 + "timezone": 7200, 52 + "id": 3165523, 53 + "name": "Province of Turin", 54 + "cod": 200 55 + }; 56 + 57 + const threeHour: ThreeHourResponse = { 58 + "cod": "200", 59 + "message": 0, 60 + "cnt": 96, 61 + "list": [ 62 + { 63 + "dt": 1661875200, 64 + "main": { 65 + "temp": 296.34, 66 + "temp_min": 296.34, 67 + "temp_max": 298.24, 68 + "pressure": 1015, 69 + "sea_level": 1015, 70 + "grnd_level": 933, 71 + "humidity": 50, 72 + "temp_kf": -1.9 73 + }, 74 + "weather": [ 75 + { 76 + "id": 500, 77 + "main": "Rain", 78 + "description": "light rain", 79 + "icon": "10d" 80 + } 81 + ], 82 + "clouds": { 83 + "all": 97 84 + }, 85 + "wind": { 86 + "speed": 1.06, 87 + "deg": 66 88 + }, 89 + "rain": { 90 + "3h": 1 91 + }, 92 + "sys": { 93 + "pod": "d" 94 + }, 95 + "dt_txt": "2022-08-30 16:00:00" 96 + }, 97 + { 98 + "dt": 1661878800, 99 + "main": { 100 + "temp": 296.31, 101 + "temp_min": 296.2, 102 + "temp_max": 296.31, 103 + "pressure": 1015, 104 + "sea_level": 1015, 105 + "grnd_level": 932, 106 + "humidity": 53, 107 + "temp_kf": 0.11 108 + }, 109 + "weather": [ 110 + { 111 + "id": 500, 112 + "main": "Rain", 113 + "description": "light rain", 114 + "icon": "10d" 115 + } 116 + ], 117 + "clouds": { 118 + "all": 95 119 + }, 120 + "wind": { 121 + "speed": 1.58, 122 + "deg": 103 123 + }, 124 + "rain": { 125 + "3h": 0.24 126 + }, 127 + "sys": { 128 + "pod": "d" 129 + }, 130 + "dt_txt": "2022-08-30 17:00:00" 131 + }, 132 + { 133 + "dt": 1661882400, 134 + "main": { 135 + "temp": 294.94, 136 + "temp_min": 292.84, 137 + "temp_max": 294.94, 138 + "pressure": 1015, 139 + "sea_level": 1015, 140 + "grnd_level": 931, 141 + "humidity": 60, 142 + "temp_kf": 2.1 143 + }, 144 + "weather": [ 145 + { 146 + "id": 500, 147 + "main": "Rain", 148 + "description": "light rain", 149 + "icon": "10n" 150 + } 151 + ], 152 + "clouds": { 153 + "all": 93 154 + }, 155 + "wind": { 156 + "speed": 1.97, 157 + "deg": 157 158 + }, 159 + "rain": { 160 + "3h": 0.2 161 + }, 162 + "sys": { 163 + "pod": "n" 164 + }, 165 + "dt_txt": "2022-08-30 18:00:00" 166 + }, 167 + { 168 + "dt": 1662217200, 169 + "main": { 170 + "temp": 294.14, 171 + "temp_min": 294.14, 172 + "temp_max": 294.14, 173 + "pressure": 1014, 174 + "sea_level": 1014, 175 + "grnd_level": 931, 176 + "humidity": 65, 177 + "temp_kf": 0 178 + }, 179 + "weather": [ 180 + { 181 + "id": 804, 182 + "main": "Clouds", 183 + "description": "overcast clouds", 184 + "icon": "04d" 185 + } 186 + ], 187 + "clouds": { 188 + "all": 100 189 + }, 190 + "wind": { 191 + "speed": 0.91, 192 + "deg": 104 193 + }, 194 + "sys": { 195 + "pod": "d" 196 + }, 197 + "dt_txt": "2022-09-03 15:00:00" 198 + } 199 + ], 200 + "city": { 201 + "id": 3163858, 202 + "name": "Zocca", 203 + "coord": { 204 + "lat": 44.34, 205 + "lon": 10.99 206 + }, 207 + "country": "IT" 208 + } 209 + } 210 + // #endregion 211 + 212 + vi.mock('openweathermap-ts', () => { 213 + return { 214 + default: { 215 + default: vi.fn().mockImplementation((_) => { 216 + return { 217 + setCityName: vi.fn(() => undefined), 218 + setCityId: vi.fn(() => undefined), 219 + setZipCode: vi.fn(() => undefined), 220 + setGeoCoordinates: vi.fn(() => undefined), 221 + getCurrentWeatherByCityName: vi.fn(async () => current), 222 + getCurrentWeatherByCityId: vi.fn(async () => current), 223 + getCurrentWeatherByZipcode: vi.fn(async () => current), 224 + getCurrentWeatherByGeoCoordinates: vi.fn(async () => current), 225 + getThreeHourForecastByCityName: vi.fn(async () => threeHour), 226 + getThreeHourForecastByCityId: vi.fn(async () => threeHour), 227 + getThreeHourForecastByZipcode: vi.fn(async () => threeHour), 228 + getThreeHourForecastByGeoCoordinates: vi.fn(async () => threeHour), 229 + } 230 + }) 231 + } 232 + } 233 + }); 234 + 235 + let weather: Weather = null; 236 + 237 + describe.for( 238 + [ 239 + { 240 + weatherFactory: () => new Weather({ 241 + key: 'api-key', 242 + city: { 243 + cityName: 'Madison', 244 + state: 'Wisconsin', 245 + countryCode: 'US' 246 + } 247 + }), 248 + by: 'CityName' 249 + }, 250 + { 251 + weatherFactory: () => new Weather({ 252 + key: 'api-key', 253 + cityid: 1 254 + }), 255 + by: 'CityId' 256 + }, 257 + { 258 + weatherFactory: () => new Weather({ 259 + key: 'api-key', 260 + zip: 53702, 261 + country: 'US' 262 + }), 263 + by: 'Zipcode' 264 + }, 265 + { 266 + weatherFactory: () => new Weather({ 267 + key: 'api-key', 268 + coordinates: [0, 0] 269 + }), 270 + by: 'GeoCoordinates' 271 + }, 272 + { 273 + weatherFactory: () => new Weather({ 274 + key: 'api-key', 275 + coordinates: '1000 , 1000' 276 + }), 277 + by: 'GeoCoordinates' 278 + } 279 + ])('weather API using city name', ({ weatherFactory, by }) => { 280 + beforeEach(() => { 281 + vi.clearAllMocks(); 282 + weather = weatherFactory(); 283 + }); 284 + 285 + it('gets current weather', async () => { 286 + expect(await weather.getCurrentWeather()).to.deep.equal(current); 287 + expect(OpenWeatherMap.default).toBeCalledWith({ 288 + apiKey: 'api-key' 289 + }); 290 + const MockedOpenWeather = vi.mocked(OpenWeatherMap.default); 291 + const openWeather = MockedOpenWeather.mock.results[0].value; 292 + expect(openWeather[`getCurrentWeatherBy${by}`]).toBeCalledTimes(1); 293 + }); 294 + 295 + it('gets the 3h forecast', async () => { 296 + expect(await weather.getThreeHourForecast()).to.deep.equal(threeHour); 297 + expect(OpenWeatherMap.default).toBeCalledWith({ 298 + apiKey: 'api-key' 299 + }); 300 + const MockedOpenWeather = vi.mocked(OpenWeatherMap.default); 301 + const openWeather = MockedOpenWeather.mock.results[0].value; 302 + expect(openWeather[`getThreeHourForecastBy${by}`]).toBeCalledTimes(1); 303 + }); 304 + 305 + it('only calls the api once', async () => { 306 + expect(await weather.getCurrentWeather()).to.deep.equal(current); 307 + expect(await weather.getCurrentWeather()).to.deep.equal(current); 308 + expect(await weather.getThreeHourForecast()).to.deep.equal(threeHour); 309 + expect(await weather.getThreeHourForecast()).to.deep.equal(threeHour); 310 + expect(OpenWeatherMap.default).toBeCalledWith({ 311 + apiKey: 'api-key' 312 + }); 313 + const MockedOpenWeather = vi.mocked(OpenWeatherMap.default); 314 + const openWeather = MockedOpenWeather.mock.results[0].value; 315 + expect(openWeather[`getCurrentWeatherBy${by}`]).toBeCalledTimes(1); 316 + expect(openWeather[`getThreeHourForecastBy${by}`]).toBeCalledTimes(1); 317 + }); 318 + } 319 + ); 320 + 321 + describe('invalid weather object', () => { 322 + beforeEach(() => { 323 + vi.clearAllMocks(); 324 + weather = new Weather({ 325 + key: 'api-key', 326 + cityid: 1 327 + }); 328 + weather['locationType'] = null; 329 + }); 330 + 331 + it('throws an exception when getCurrentWeather is called', async () => { 332 + await expect(weather.getCurrentWeather()).rejects.toThrow(/location type/); 333 + }); 334 + 335 + it('throws an exception when getThreeHourForecast is called', async () => { 336 + await expect(weather.getThreeHourForecast()).rejects.toThrow(/location type/); 337 + }); 338 + });