From 91fd921e2e0c759ce9ea76f7571b81ccc6f405bd Mon Sep 17 00:00:00 2001 From: Djuri Baars Date: Wed, 8 Nov 2023 12:18:59 +0100 Subject: [PATCH] LEDs and buttons working --- .gitignore | 8 +- data/.yarnrc.yml | 1 + data/esbuild.mjs | 50 + data/package.json | 23 + data/src/css/oswald.woff | Bin 0 -> 12732 bytes data/src/css/oswald.woff2 | Bin 0 -> 9840 bytes data/src/css/style.scss | 121 ++ data/src/font/oswald.css | 0 data/src/index.html | 235 ++++ data/src/js/helpers.js | 17 + data/src/js/script.ts | 187 +++ data/src/wifi.html | 48 + data/tsconfig.json | 6 + data/yarn.lock | 2728 ++++++++++++++++++++++++++++++++++++ scripts/extra_script.py | 2 +- src/lib/block_notify.cpp | 25 +- src/lib/block_notify.hpp | 5 +- src/lib/button_handler.cpp | 31 +- src/lib/button_handler.hpp | 1 + src/lib/config.cpp | 90 +- src/lib/config.hpp | 7 +- src/lib/epd.cpp | 4 +- src/lib/led_handler.cpp | 204 ++- src/lib/led_handler.hpp | 26 + src/lib/price_notify.cpp | 9 +- src/lib/price_notify.hpp | 3 +- src/lib/screen_handler.cpp | 86 +- src/lib/screen_handler.hpp | 7 +- src/lib/shared.hpp | 2 + src/lib/utils.cpp | 6 + src/lib/utils.hpp | 1 + src/lib/webserver.cpp | 74 +- src/lib/webserver.hpp | 6 +- 33 files changed, 3877 insertions(+), 136 deletions(-) create mode 100644 data/.yarnrc.yml create mode 100644 data/esbuild.mjs create mode 100644 data/package.json create mode 100644 data/src/css/oswald.woff create mode 100644 data/src/css/oswald.woff2 create mode 100644 data/src/css/style.scss create mode 100644 data/src/font/oswald.css create mode 100644 data/src/index.html create mode 100644 data/src/js/helpers.js create mode 100644 data/src/js/script.ts create mode 100644 data/src/wifi.html create mode 100644 data/tsconfig.json create mode 100644 data/yarn.lock create mode 100644 src/lib/utils.cpp create mode 100644 src/lib/utils.hpp diff --git a/.gitignore b/.gitignore index 405e1b6..e5f0444 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,10 @@ .vscode/launch.json .vscode/ipch managed_components -data/build/* \ No newline at end of file +data/build/* +data/build +data/.yarn +data/node_modules +node_modules +.DS_Store +*.bin \ No newline at end of file diff --git a/data/.yarnrc.yml b/data/.yarnrc.yml new file mode 100644 index 0000000..3186f3f --- /dev/null +++ b/data/.yarnrc.yml @@ -0,0 +1 @@ +nodeLinker: node-modules diff --git a/data/esbuild.mjs b/data/esbuild.mjs new file mode 100644 index 0000000..7c51538 --- /dev/null +++ b/data/esbuild.mjs @@ -0,0 +1,50 @@ +import esbuild from "esbuild"; +import { sassPlugin } from "esbuild-sass-plugin"; +import htmlPlugin from '@chialab/esbuild-plugin-html'; +import handlebarsPlugin from "esbuild-plugin-handlebars"; +import { clean } from 'esbuild-plugin-clean'; + +import postcss from "postcss"; +import autoprefixer from "autoprefixer"; + +const hbsOptions = { + additionalHelpers: { splitText: "helpers.js" }, + additionalPartials: {}, + precompileOptions: {} + } + +esbuild + .build({ + entryPoints: ["src/css/style.scss", "src/js/script.ts", "src/index.html", "src/js/helpers.js"], + outdir: "build", + bundle: true, + loader: { + ".png": "dataurl", + ".woff": "dataurl", + ".woff2": "dataurl", + ".eot": "dataurl", + ".ttf": "dataurl", + ".svg": "dataurl", + }, + plugins: [ + clean({ + patterns: ['./build/*'] + }), + htmlPlugin(), + sassPlugin({ + async transform(source) { + const { css } = await postcss([autoprefixer]).process( + source + , { from: undefined }); + return css; + }, + }), + handlebarsPlugin(hbsOptions), + + ], + minify: true, + metafile: false, + sourcemap: false + }) + .then(() => console.log("⚡ Build complete! ⚡")) + .catch(() => process.exit(1)); \ No newline at end of file diff --git a/data/package.json b/data/package.json new file mode 100644 index 0000000..2ef41d5 --- /dev/null +++ b/data/package.json @@ -0,0 +1,23 @@ +{ + "name": "data", + "packageManager": "yarn@3.2.1", + "scripts": { + "build": "node esbuild.mjs" + }, + "dependencies": { + "esbuild": "0.19.4" + }, + "devDependencies": { + "@chialab/esbuild-plugin-html": "^0.17.2", + "@craftamap/esbuild-plugin-html": "^0.5.0", + "@esbuilder/html": "^0.0.6", + "autoprefixer": "^10.4.16", + "bootstrap": "^5.3.2", + "esbuild-plugin-clean": "^1.0.1", + "esbuild-plugin-handlebars": "^1.0.2", + "esbuild-sass-plugin": "^2.16.0", + "handlebars": "^4.7.7", + "postcss": "^8.4.31", + "typescript": "^5.1.6" + } +} diff --git a/data/src/css/oswald.woff b/data/src/css/oswald.woff new file mode 100644 index 0000000000000000000000000000000000000000..aab7cddd25b5208f12686d6f71bfb472a0db905e GIT binary patch literal 12732 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 literal 0 HcmV?d00001 diff --git a/data/src/css/oswald.woff2 b/data/src/css/oswald.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..7ef4f1dea197b5b1b2f7d453a05a43620f96f816 GIT binary patch literal 9840 zcmV-$CXd;7Pew8T0RR91048t%5C8xG08$J9045Ot0RR9100000000000000000000 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 W3TRq*809*w+)O6%Vf;6~h$R4lgfznd literal 0 HcmV?d00001 diff --git a/data/src/css/style.scss b/data/src/css/style.scss new file mode 100644 index 0000000..fe56410 --- /dev/null +++ b/data/src/css/style.scss @@ -0,0 +1,121 @@ +// @import "../node_modules/bootstrap/scss/bootstrap"; + +@import "../node_modules/bootstrap/scss/functions"; +@import "../node_modules/bootstrap/scss/variables"; +@import "../node_modules/bootstrap/scss/variables-dark"; + +$form-range-track-bg: #fff; + +@import "../node_modules/bootstrap/scss/mixins"; +@import "../node_modules/bootstrap/scss/maps"; +@import "../node_modules/bootstrap/scss/utilities"; + +@import "../node_modules/bootstrap/scss/root"; +@import "../node_modules/bootstrap/scss/reboot"; +@import "../node_modules/bootstrap/scss/type"; +@import "../node_modules/bootstrap/scss/containers"; +@import "../node_modules/bootstrap/scss/grid"; +@import "../node_modules/bootstrap/scss/forms"; +@import "../node_modules/bootstrap/scss/buttons"; +@import "../node_modules/bootstrap/scss/navbar"; +@import "../node_modules/bootstrap/scss/nav"; +@import "../node_modules/bootstrap/scss/card"; +@import "../node_modules/bootstrap/scss/progress"; + +@import "../node_modules/bootstrap/scss/helpers"; +@import "../node_modules/bootstrap/scss/utilities/api"; + + +@font-face { + font-display: swap; + /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ + font-family: 'Oswald'; + font-style: normal; + font-weight: 400; + src: url('oswald.woff2') format('woff2'), + /* Chrome 36+, Opera 23+, Firefox 39+ */ + url('oswald.woff') format('woff'); + /* Chrome 5+, Firefox 3.6+, IE 9+, Safari 5.1+ */ +} + +nav { + margin-bottom: 15px; +} + +.splitText div:first-child::after { + display: block; + content: ''; + margin-top: 0px; + border-bottom: 2px solid; + margin-bottom: 3px; +} + +#btcclock-wrapper { + margin: 0 auto; +} + +.btclock { + display: flex; + flex-direction: row; + flex-wrap: nowrap; + justify-content: space-between; + align-items: center; + align-content: stretch; + font-family: 'Oswald', sans-serif; +} + +.btclock>div { + padding: 5px; +} + +.fg-ffff .btclock>div { + color: #fff; + border-color: #fff; +} + +.bg-ffff .btclock>div { + background: #fff; +} + +.fg-f800 .btclock>div { + color: #f00; + border-color: #f00; +} + +.bg-f800 .btclock>div { + background: #f00; +} + +.fg-0 .btclock>div { + color: #000; + border-color: #000; +} + +.bg-0 .btclock>div { + background: #000; +} + +.splitText { + font-size: 2.2rem; + padding-top: 5px; + padding-bottom: 5px; + text-align: center; +} + +.digit { + font-size: 5rem; + padding-left: 10px; + padding-right: 10px; +} + +.digit-blank { + content: "abc"; +} + +#customText { + text-transform: uppercase; +} + +#toggleTimerArea { + cursor: pointer; +} \ No newline at end of file diff --git a/data/src/font/oswald.css b/data/src/font/oswald.css new file mode 100644 index 0000000..e69de29 diff --git a/data/src/index.html b/data/src/index.html new file mode 100644 index 0000000..0dd9860 --- /dev/null +++ b/data/src/index.html @@ -0,0 +1,235 @@ + + + + + + + + + ₿TClock + + + + + + +
+
+
+
+

Custom text

+
+
+ +
+ +
+
+
+ + +
+
+
+

LEDs

+
+
+ +
+ +
+
+ + +
+
+
+
+
+
+
+
+

Settings

+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+
+ + minutes +
+ +
+
+
+ +
+
+ + minutes +
+
+
+
+ +
+
+ + min + +
+
A restart is required to apply TZ offset.
+
+
+
+
+
+ + +
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+ +

Screens

+
+ + +
+ +
+
+
+
+
+ + + + +
+ + + + \ No newline at end of file diff --git a/data/src/js/helpers.js b/data/src/js/helpers.js new file mode 100644 index 0000000..b72a537 --- /dev/null +++ b/data/src/js/helpers.js @@ -0,0 +1,17 @@ +//import "handlebars/dist/handlebars.js"; + +Handlebars.registerHelper('splitText', function (aString) { + if (aString.includes("/")) { + var c = aString.split("/").map((el) => { return "
" + el + "
"; }).join(''); + return "
" + c + "
"; + } + if (aString.length == 0 || aString === " ") { + aString = "  "; + } + //return aString; + return "
" + aString + "
"; + }); + +Handlebars.registerHelper('ifEquals', function(arg1, arg2, options) { + return (arg1 == arg2) ? options.fn(this) : options.inverse(this); +}); \ No newline at end of file diff --git a/data/src/js/script.ts b/data/src/js/script.ts new file mode 100644 index 0000000..1000cf6 --- /dev/null +++ b/data/src/js/script.ts @@ -0,0 +1,187 @@ +import './helpers.js'; + +var screens = ["Block Height", "Moscow Time", "Ticker", "Time", "Halving countdown"]; + +toTime = (secs) => { + var hours = Math.floor(secs / (60 * 60)); + + var divisor_for_minutes = secs % (60 * 60); + var minutes = Math.floor(divisor_for_minutes / 60); + + var divisor_for_seconds = divisor_for_minutes % 60; + var seconds = Math.ceil(divisor_for_seconds); + + var obj = { + "h": hours, + "m": minutes, + "s": seconds + }; + return obj; +} + +getBcStatus = () => { + fetch('/api/status', { + method: 'get' + }) + .then(response => response.json()) + .then(jsonData => { + var source = document.getElementById("entry-template").innerHTML; + var template = Handlebars.compile(source); + + var context = { + timerRunning: jsonData.timerRunning, + memUsage: Math.round(jsonData.espFreeHeap / jsonData.espHeapSize * 100), + memFree: Math.round(jsonData.espFreeHeap / 1024), + memTotal: Math.round(jsonData.espHeapSize / 1024), + uptime: toTime(jsonData.espUptime), + currentScreen: jsonData.currentScreen, + rendered: jsonData.rendered, + data: jsonData.data, + screens: screens, + ledStatus: jsonData.ledStatus ? jsonData.ledStatus.map((t) => (t).toString(16)) : [], + connectionStatus: jsonData.connectionStatus + }; + + + document.getElementById('output').innerHTML = template(context); + }) + .catch(err => { + //error block + }); +} + +interval = setInterval(getBcStatus, 2500); +getBcStatus(); + +fetch('/api/settings', { + method: 'get' +}) + .then(response => response.json()) + .then(jsonData => { + var fgColor = ("0x" + jsonData.fgColor.toString(16).toUpperCase()); + if (jsonData.epdColors == 2) { + document.getElementById('fgColor').querySelector('[value="0xF800"]').remove(); + document.getElementById('bgColor').querySelector('[value="0xF800"]').remove(); + } + + document.getElementById('customText').setAttribute('maxlength', jsonData.numScreens); + document.getElementById('output').classList.add("fg-" + jsonData.fgColor.toString(16)); + document.getElementById('output').classList.add("bg-" + jsonData.bgColor.toString(16)); + + document.getElementById('fgColor').value = fgColor; + document.getElementById('bgColor').value = "0x" + jsonData.bgColor.toString(16).toUpperCase(); + + if (jsonData.ledFlashOnUpdate) + document.getElementById('ledFlashOnUpdate').checked = true; + + if (jsonData.useBitcoinNode) + document.getElementById('useBitcoinNode').checked = true; + + let nodeFields = ["rpcHost", "rpcPort", "rpcUser", "tzOffset"]; + + for (let n of nodeFields) { + document.getElementById(n).value = jsonData[n]; + } + + document.getElementById('timePerScreen').value = jsonData.timerSeconds / 60; + document.getElementById('ledBrightness').value = jsonData.ledBrightness; + document.getElementById('fullRefreshMin').value = jsonData.fullRefreshMin; + document.getElementById('wpTimeout').value = jsonData.wpTimeout; + document.getElementById('mempoolInstance').value = jsonData.mempoolInstance; + + if (jsonData.gitRev) + document.getElementById('gitRev').innerHTML = "Version: " + jsonData.gitRev; + + if (jsonData.lastBuildTime) + document.getElementById('lastBuildTime').innerHTML = " / " + new Date((jsonData.lastBuildTime * 1000)).toLocaleString(); + + var source = document.getElementById("screens-template").innerHTML; + var template = Handlebars.compile(source); + var context = { screens: jsonData.screens }; + document.getElementById('outputScreens').innerHTML = template(context); + }) + .catch(err => { + console.log('error', err); + }); + + + +var settingsForm = document.querySelector('#settingsForm'); +settingsForm.onsubmit = (event) => { + var formData = new FormData(settingsForm); + + fetch("/api/settings", + { + body: formData, + method: "post" + }).then(() => { + console.log('Submitted'); + document.getElementById('saveSettingsBtn')?.classList.add('btn-success'); + }); + + return false; +} + +document.getElementById('restartBtn').onclick = (event) => { + fetch('/api/restart'); + return false; +} + + +var ledsForm = document.querySelector('#ledsForm'); +ledsForm.onsubmit = (event) => { + var formData = new FormData(ledsForm); + + fetch('/api/lights/' + encodeURIComponent(formData.get('pickedColor').substring(1)), { + method: 'get' + }) + + return false; +} + +turnOffLedsBtn.onclick = (event) => { + fetch('/api/lights/off', { + method: 'get' + }) + return false; +} + +let tzOffsetBtn = document.getElementById('getTzOffsetBtn'); + +if (tzOffsetBtn) + tzOffsetBtn.onclick = (event) => { + document.getElementById("tzOffset").value = new Date(new Date().getFullYear(), 0, 1).getTimezoneOffset() * -1; + return false; + }; + +var textForm = document.querySelector('#customTextForm'); +textForm.onsubmit = (event) => { + var formData = new FormData(textForm); + + fetch('/api/show/text/' + encodeURIComponent(formData.get('customText')), { + method: 'get' + }) + .then(response => response.json()) + .catch(err => { + //error block + }); + return false; +} + +changeScreen = (id) => { + fetch('/api/show/screen/' + encodeURIComponent(id), { + method: 'get' + }) + .then(response => response.json()) + .catch(err => { + //error block + }); +} + +toggleTimer = (currentStatus) => { + if (currentStatus) { + fetch('/api/action/pause'); + } else { + fetch('/api/action/timer_restart'); + } +} \ No newline at end of file diff --git a/data/src/wifi.html b/data/src/wifi.html new file mode 100644 index 0000000..e0167ae --- /dev/null +++ b/data/src/wifi.html @@ -0,0 +1,48 @@ + + + + + + + + + ₿TClock WiFi Settings + + + + + +
+
+
+
+

WiFi Settings

+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +

The BTClock will restart and connect to your network. If it doesn't, reset to factory settings by holding the red button while booting to retry.

+
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/data/tsconfig.json b/data/tsconfig.json new file mode 100644 index 0000000..9292693 --- /dev/null +++ b/data/tsconfig.json @@ -0,0 +1,6 @@ +{ + "files": ["src/js/**.ts"], + "compilerOptions": { + "noImplicitAny": true, + } + } \ No newline at end of file diff --git a/data/yarn.lock b/data/yarn.lock new file mode 100644 index 0000000..acf9133 --- /dev/null +++ b/data/yarn.lock @@ -0,0 +1,2728 @@ +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! + +__metadata: + version: 6 + cacheKey: 8 + +"@chialab/esbuild-plugin-html@npm:^0.17.2": + version: 0.17.3 + resolution: "@chialab/esbuild-plugin-html@npm:0.17.3" + dependencies: + "@chialab/esbuild-rna": ^0.17.8 + "@chialab/node-resolve": ^0.17.1 + checksum: b15e41fe804971a91136c30a46345ef0c2902e5ff472a3da8a33a433daefeb709d9e71b89e21b050108918c18bd5d44e55750152c23915b0287cb07a6adf3fae + languageName: node + linkType: hard + +"@chialab/esbuild-rna@npm:^0.17.8": + version: 0.17.8 + resolution: "@chialab/esbuild-rna@npm:0.17.8" + dependencies: + "@chialab/estransform": ^0.17.4 + "@chialab/node-resolve": ^0.17.1 + checksum: 640590b7d4587032c47bda80aff1b907ef5f878506716f4073208ea28015d5e80008d1127a4e717a739a8916a9946263e3df92d3650ada6e6bace9c44594a044 + languageName: node + linkType: hard + +"@chialab/estransform@npm:^0.17.4": + version: 0.17.4 + resolution: "@chialab/estransform@npm:0.17.4" + dependencies: + "@parcel/source-map": ^2.0.0 + checksum: e6fd9a56793c1697dc120b1a4c9ff4a9489c84b8871af0f8d12b4b65c95dba8e15d3f591827d52cf9a79954d75ddb022de7e60899bd062fdd081e42e7efb4bcb + languageName: node + linkType: hard + +"@chialab/node-resolve@npm:^0.17.1": + version: 0.17.1 + resolution: "@chialab/node-resolve@npm:0.17.1" + checksum: 1f06085c9706bcbd5656eda1afc386757f475daa7a92ceb890a6dd5814035620964fbe99948d68bd0db0d1c4666a6c1d8246593bb105cd3393188597741bc212 + languageName: node + linkType: hard + +"@craftamap/esbuild-plugin-html@npm:^0.5.0": + version: 0.5.0 + resolution: "@craftamap/esbuild-plugin-html@npm:0.5.0" + dependencies: + jsdom: ^17.0.0 + lodash.template: ^4.5.0 + peerDependencies: + esbuild: ">=0.15.10" + checksum: 2ab22a46667b4c91cbfdeda2ab7d0d501435e1be1ce6d3ad7643832b23b2549073ed34ed2f61491ab480bf6a8dbac70c43baebdf0f76ff8bc3ebfaa66e218408 + languageName: node + linkType: hard + +"@esbuild/android-arm64@npm:0.19.4": + version: 0.19.4 + resolution: "@esbuild/android-arm64@npm:0.19.4" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/android-arm@npm:0.19.4": + version: 0.19.4 + resolution: "@esbuild/android-arm@npm:0.19.4" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@esbuild/android-x64@npm:0.19.4": + version: 0.19.4 + resolution: "@esbuild/android-x64@npm:0.19.4" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/darwin-arm64@npm:0.19.4": + version: 0.19.4 + resolution: "@esbuild/darwin-arm64@npm:0.19.4" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/darwin-x64@npm:0.19.4": + version: 0.19.4 + resolution: "@esbuild/darwin-x64@npm:0.19.4" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/freebsd-arm64@npm:0.19.4": + version: 0.19.4 + resolution: "@esbuild/freebsd-arm64@npm:0.19.4" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/freebsd-x64@npm:0.19.4": + version: 0.19.4 + resolution: "@esbuild/freebsd-x64@npm:0.19.4" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/linux-arm64@npm:0.19.4": + version: 0.19.4 + resolution: "@esbuild/linux-arm64@npm:0.19.4" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/linux-arm@npm:0.19.4": + version: 0.19.4 + resolution: "@esbuild/linux-arm@npm:0.19.4" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@esbuild/linux-ia32@npm:0.19.4": + version: 0.19.4 + resolution: "@esbuild/linux-ia32@npm:0.19.4" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/linux-loong64@npm:0.19.4": + version: 0.19.4 + resolution: "@esbuild/linux-loong64@npm:0.19.4" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + +"@esbuild/linux-mips64el@npm:0.19.4": + version: 0.19.4 + resolution: "@esbuild/linux-mips64el@npm:0.19.4" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + +"@esbuild/linux-ppc64@npm:0.19.4": + version: 0.19.4 + resolution: "@esbuild/linux-ppc64@npm:0.19.4" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/linux-riscv64@npm:0.19.4": + version: 0.19.4 + resolution: "@esbuild/linux-riscv64@npm:0.19.4" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + +"@esbuild/linux-s390x@npm:0.19.4": + version: 0.19.4 + resolution: "@esbuild/linux-s390x@npm:0.19.4" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + +"@esbuild/linux-x64@npm:0.19.4": + version: 0.19.4 + resolution: "@esbuild/linux-x64@npm:0.19.4" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/netbsd-x64@npm:0.19.4": + version: 0.19.4 + resolution: "@esbuild/netbsd-x64@npm:0.19.4" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openbsd-x64@npm:0.19.4": + version: 0.19.4 + resolution: "@esbuild/openbsd-x64@npm:0.19.4" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/sunos-x64@npm:0.19.4": + version: 0.19.4 + resolution: "@esbuild/sunos-x64@npm:0.19.4" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/win32-arm64@npm:0.19.4": + version: 0.19.4 + resolution: "@esbuild/win32-arm64@npm:0.19.4" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/win32-ia32@npm:0.19.4": + version: 0.19.4 + resolution: "@esbuild/win32-ia32@npm:0.19.4" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/win32-x64@npm:0.19.4": + version: 0.19.4 + resolution: "@esbuild/win32-x64@npm:0.19.4" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@esbuilder/html@npm:^0.0.6": + version: 0.0.6 + resolution: "@esbuilder/html@npm:0.0.6" + dependencies: + cheerio: ^1.0.0-rc.12 + tslib: ^2.4.0 + peerDependencies: + esbuild: ">=0.14.42" + checksum: 17a7c3e39465ebee452e244e115fec8dc04bb19852c1a72c1127f272323d0876a79ce95a9d5215c03cdf5a5178b7f41926b6d96cd8b891ee286863b80722b8ef + languageName: node + linkType: hard + +"@isaacs/cliui@npm:^8.0.2": + version: 8.0.2 + resolution: "@isaacs/cliui@npm:8.0.2" + dependencies: + string-width: ^5.1.2 + string-width-cjs: "npm:string-width@^4.2.0" + strip-ansi: ^7.0.1 + strip-ansi-cjs: "npm:strip-ansi@^6.0.1" + wrap-ansi: ^8.1.0 + wrap-ansi-cjs: "npm:wrap-ansi@^7.0.0" + checksum: 4a473b9b32a7d4d3cfb7a614226e555091ff0c5a29a1734c28c72a182c2f6699b26fc6b5c2131dfd841e86b185aea714c72201d7c98c2fba5f17709333a67aeb + languageName: node + linkType: hard + +"@nodelib/fs.scandir@npm:2.1.5": + version: 2.1.5 + resolution: "@nodelib/fs.scandir@npm:2.1.5" + dependencies: + "@nodelib/fs.stat": 2.0.5 + run-parallel: ^1.1.9 + checksum: a970d595bd23c66c880e0ef1817791432dbb7acbb8d44b7e7d0e7a22f4521260d4a83f7f9fd61d44fda4610105577f8f58a60718105fb38352baed612fd79e59 + languageName: node + linkType: hard + +"@nodelib/fs.stat@npm:2.0.5, @nodelib/fs.stat@npm:^2.0.2": + version: 2.0.5 + resolution: "@nodelib/fs.stat@npm:2.0.5" + checksum: 012480b5ca9d97bff9261571dbbec7bbc6033f69cc92908bc1ecfad0792361a5a1994bc48674b9ef76419d056a03efadfce5a6cf6dbc0a36559571a7a483f6f0 + languageName: node + linkType: hard + +"@nodelib/fs.walk@npm:^1.2.3": + version: 1.2.8 + resolution: "@nodelib/fs.walk@npm:1.2.8" + dependencies: + "@nodelib/fs.scandir": 2.1.5 + fastq: ^1.6.0 + checksum: 190c643f156d8f8f277bf2a6078af1ffde1fd43f498f187c2db24d35b4b4b5785c02c7dc52e356497b9a1b65b13edc996de08de0b961c32844364da02986dc53 + languageName: node + linkType: hard + +"@npmcli/fs@npm:^3.1.0": + version: 3.1.0 + resolution: "@npmcli/fs@npm:3.1.0" + dependencies: + semver: ^7.3.5 + checksum: a50a6818de5fc557d0b0e6f50ec780a7a02ab8ad07e5ac8b16bf519e0ad60a144ac64f97d05c443c3367235d337182e1d012bbac0eb8dbae8dc7b40b193efd0e + languageName: node + linkType: hard + +"@parcel/source-map@npm:^2.0.0": + version: 2.1.1 + resolution: "@parcel/source-map@npm:2.1.1" + dependencies: + detect-libc: ^1.0.3 + checksum: 1fa27a7047ec08faf7fe1dd0e2ae95a27b84697ecfaed029d0b7d06e46d84ed8f98a9dc9d308fe623655f3c985052dcf7622de479bfa6103c44884fb7f6c810a + languageName: node + linkType: hard + +"@pkgjs/parseargs@npm:^0.11.0": + version: 0.11.0 + resolution: "@pkgjs/parseargs@npm:0.11.0" + checksum: 6ad6a00fc4f2f2cfc6bff76fb1d88b8ee20bc0601e18ebb01b6d4be583733a860239a521a7fbca73b612e66705078809483549d2b18f370eb346c5155c8e4a0f + languageName: node + linkType: hard + +"@tootallnate/once@npm:1": + version: 1.1.2 + resolution: "@tootallnate/once@npm:1.1.2" + checksum: e1fb1bbbc12089a0cb9433dc290f97bddd062deadb6178ce9bcb93bb7c1aecde5e60184bc7065aec42fe1663622a213493c48bbd4972d931aae48315f18e1be9 + languageName: node + linkType: hard + +"@tootallnate/once@npm:2": + version: 2.0.0 + resolution: "@tootallnate/once@npm:2.0.0" + checksum: ad87447820dd3f24825d2d947ebc03072b20a42bfc96cbafec16bff8bbda6c1a81fcb0be56d5b21968560c5359a0af4038a68ba150c3e1694fe4c109a063bed8 + languageName: node + linkType: hard + +"abab@npm:^2.0.5, abab@npm:^2.0.6": + version: 2.0.6 + resolution: "abab@npm:2.0.6" + checksum: 6ffc1af4ff315066c62600123990d87551ceb0aafa01e6539da77b0f5987ac7019466780bf480f1787576d4385e3690c81ccc37cfda12819bf510b8ab47e5a3e + languageName: node + linkType: hard + +"abbrev@npm:^1.0.0": + version: 1.1.1 + resolution: "abbrev@npm:1.1.1" + checksum: a4a97ec07d7ea112c517036882b2ac22f3109b7b19077dc656316d07d308438aac28e4d9746dc4d84bf6b1e75b4a7b0a5f3cb30592419f128ca9a8cee3bcfa17 + languageName: node + linkType: hard + +"acorn-globals@npm:^6.0.0": + version: 6.0.0 + resolution: "acorn-globals@npm:6.0.0" + dependencies: + acorn: ^7.1.1 + acorn-walk: ^7.1.1 + checksum: 72d95e5b5e585f9acd019b993ab8bbba68bb3cbc9d9b5c1ebb3c2f1fe5981f11deababfb4949f48e6262f9c57878837f5958c0cca396f81023814680ca878042 + languageName: node + linkType: hard + +"acorn-walk@npm:^7.1.1": + version: 7.2.0 + resolution: "acorn-walk@npm:7.2.0" + checksum: 9252158a79b9d92f1bc0dd6acc0fcfb87a67339e84bcc301bb33d6078936d27e35d606b4d35626d2962cd43c256d6f27717e70cbe15c04fff999ab0b2260b21f + languageName: node + linkType: hard + +"acorn@npm:^7.1.1": + version: 7.4.1 + resolution: "acorn@npm:7.4.1" + bin: + acorn: bin/acorn + checksum: 1860f23c2107c910c6177b7b7be71be350db9e1080d814493fae143ae37605189504152d1ba8743ba3178d0b37269ce1ffc42b101547fdc1827078f82671e407 + languageName: node + linkType: hard + +"acorn@npm:^8.4.1": + version: 8.10.0 + resolution: "acorn@npm:8.10.0" + bin: + acorn: bin/acorn + checksum: 538ba38af0cc9e5ef983aee196c4b8b4d87c0c94532334fa7e065b2c8a1f85863467bb774231aae91613fcda5e68740c15d97b1967ae3394d20faddddd8af61d + languageName: node + linkType: hard + +"agent-base@npm:6, agent-base@npm:^6.0.2": + version: 6.0.2 + resolution: "agent-base@npm:6.0.2" + dependencies: + debug: 4 + checksum: f52b6872cc96fd5f622071b71ef200e01c7c4c454ee68bc9accca90c98cfb39f2810e3e9aa330435835eedc8c23f4f8a15267f67c6e245d2b33757575bdac49d + languageName: node + linkType: hard + +"agentkeepalive@npm:^4.2.1": + version: 4.5.0 + resolution: "agentkeepalive@npm:4.5.0" + dependencies: + humanize-ms: ^1.2.1 + checksum: 13278cd5b125e51eddd5079f04d6fe0914ac1b8b91c1f3db2c1822f99ac1a7457869068997784342fe455d59daaff22e14fb7b8c3da4e741896e7e31faf92481 + languageName: node + linkType: hard + +"aggregate-error@npm:^3.0.0": + version: 3.1.0 + resolution: "aggregate-error@npm:3.1.0" + dependencies: + clean-stack: ^2.0.0 + indent-string: ^4.0.0 + checksum: 1101a33f21baa27a2fa8e04b698271e64616b886795fd43c31068c07533c7b3facfcaf4e9e0cab3624bd88f729a592f1c901a1a229c9e490eafce411a8644b79 + languageName: node + linkType: hard + +"ansi-regex@npm:^5.0.1": + version: 5.0.1 + resolution: "ansi-regex@npm:5.0.1" + checksum: 2aa4bb54caf2d622f1afdad09441695af2a83aa3fe8b8afa581d205e57ed4261c183c4d3877cee25794443fde5876417d859c108078ab788d6af7e4fe52eb66b + languageName: node + linkType: hard + +"ansi-regex@npm:^6.0.1": + version: 6.0.1 + resolution: "ansi-regex@npm:6.0.1" + checksum: 1ff8b7667cded1de4fa2c9ae283e979fc87036864317da86a2e546725f96406746411d0d85e87a2d12fa5abd715d90006de7fa4fa0477c92321ad3b4c7d4e169 + languageName: node + linkType: hard + +"ansi-styles@npm:^4.0.0, ansi-styles@npm:^4.1.0": + version: 4.3.0 + resolution: "ansi-styles@npm:4.3.0" + dependencies: + color-convert: ^2.0.1 + checksum: 513b44c3b2105dd14cc42a19271e80f386466c4be574bccf60b627432f9198571ebf4ab1e4c3ba17347658f4ee1711c163d574248c0c1cdc2d5917a0ad582ec4 + languageName: node + linkType: hard + +"ansi-styles@npm:^6.1.0": + version: 6.2.1 + resolution: "ansi-styles@npm:6.2.1" + checksum: ef940f2f0ced1a6347398da88a91da7930c33ecac3c77b72c5905f8b8fe402c52e6fde304ff5347f616e27a742da3f1dc76de98f6866c69251ad0b07a66776d9 + languageName: node + linkType: hard + +"anymatch@npm:~3.1.2": + version: 3.1.3 + resolution: "anymatch@npm:3.1.3" + dependencies: + normalize-path: ^3.0.0 + picomatch: ^2.0.4 + checksum: 3e044fd6d1d26545f235a9fe4d7a534e2029d8e59fa7fd9f2a6eb21230f6b5380ea1eaf55136e60cbf8e613544b3b766e7a6fa2102e2a3a117505466e3025dc2 + languageName: node + linkType: hard + +"aproba@npm:^1.0.3 || ^2.0.0": + version: 2.0.0 + resolution: "aproba@npm:2.0.0" + checksum: 5615cadcfb45289eea63f8afd064ab656006361020e1735112e346593856f87435e02d8dcc7ff0d11928bc7d425f27bc7c2a84f6c0b35ab0ff659c814c138a24 + languageName: node + linkType: hard + +"are-we-there-yet@npm:^3.0.0": + version: 3.0.1 + resolution: "are-we-there-yet@npm:3.0.1" + dependencies: + delegates: ^1.0.0 + readable-stream: ^3.6.0 + checksum: 52590c24860fa7173bedeb69a4c05fb573473e860197f618b9a28432ee4379049336727ae3a1f9c4cb083114601c1140cee578376164d0e651217a9843f9fe83 + languageName: node + linkType: hard + +"array-union@npm:^2.1.0": + version: 2.1.0 + resolution: "array-union@npm:2.1.0" + checksum: 5bee12395cba82da674931df6d0fea23c4aa4660cb3b338ced9f828782a65caa232573e6bf3968f23e0c5eb301764a382cef2f128b170a9dc59de0e36c39f98d + languageName: node + linkType: hard + +"asynckit@npm:^0.4.0": + version: 0.4.0 + resolution: "asynckit@npm:0.4.0" + checksum: 7b78c451df768adba04e2d02e63e2d0bf3b07adcd6e42b4cf665cb7ce899bedd344c69a1dcbce355b5f972d597b25aaa1c1742b52cffd9caccb22f348114f6be + languageName: node + linkType: hard + +"autoprefixer@npm:^10.4.16": + version: 10.4.16 + resolution: "autoprefixer@npm:10.4.16" + dependencies: + browserslist: ^4.21.10 + caniuse-lite: ^1.0.30001538 + fraction.js: ^4.3.6 + normalize-range: ^0.1.2 + picocolors: ^1.0.0 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.1.0 + bin: + autoprefixer: bin/autoprefixer + checksum: 45fad7086495048dacb14bb7b00313e70e135b5d8e8751dcc60548889400763705ab16fc2d99ea628b44c3472698fb0e39598f595ba28409c965ab159035afde + languageName: node + linkType: hard + +"balanced-match@npm:^1.0.0": + version: 1.0.2 + resolution: "balanced-match@npm:1.0.2" + checksum: 9706c088a283058a8a99e0bf91b0a2f75497f185980d9ffa8b304de1d9e58ebda7c72c07ebf01dadedaac5b2907b2c6f566f660d62bd336c3468e960403b9d65 + languageName: node + linkType: hard + +"binary-extensions@npm:^2.0.0": + version: 2.2.0 + resolution: "binary-extensions@npm:2.2.0" + checksum: ccd267956c58d2315f5d3ea6757cf09863c5fc703e50fbeb13a7dc849b812ef76e3cf9ca8f35a0c48498776a7478d7b4a0418e1e2b8cb9cb9731f2922aaad7f8 + languageName: node + linkType: hard + +"boolbase@npm:^1.0.0": + version: 1.0.0 + resolution: "boolbase@npm:1.0.0" + checksum: 3e25c80ef626c3a3487c73dbfc70ac322ec830666c9ad915d11b701142fab25ec1e63eff2c450c74347acfd2de854ccde865cd79ef4db1683f7c7b046ea43bb0 + languageName: node + linkType: hard + +"bootstrap@npm:^5.3.2": + version: 5.3.2 + resolution: "bootstrap@npm:5.3.2" + peerDependencies: + "@popperjs/core": ^2.11.8 + checksum: d5580b253d121ffc137388d41da58dce8d15f1ccd574e12f28d4a08e7649ca15e95db645b2b677cb8025bccd446bff04138fc0fe64f8cba0ccc5dc004a8644cf + languageName: node + linkType: hard + +"brace-expansion@npm:^1.1.7": + version: 1.1.11 + resolution: "brace-expansion@npm:1.1.11" + dependencies: + balanced-match: ^1.0.0 + concat-map: 0.0.1 + checksum: faf34a7bb0c3fcf4b59c7808bc5d2a96a40988addf2e7e09dfbb67a2251800e0d14cd2bfc1aa79174f2f5095c54ff27f46fb1289fe2d77dac755b5eb3434cc07 + languageName: node + linkType: hard + +"brace-expansion@npm:^2.0.1": + version: 2.0.1 + resolution: "brace-expansion@npm:2.0.1" + dependencies: + balanced-match: ^1.0.0 + checksum: a61e7cd2e8a8505e9f0036b3b6108ba5e926b4b55089eeb5550cd04a471fe216c96d4fe7e4c7f995c728c554ae20ddfc4244cad10aef255e72b62930afd233d1 + languageName: node + linkType: hard + +"braces@npm:^3.0.2, braces@npm:~3.0.2": + version: 3.0.2 + resolution: "braces@npm:3.0.2" + dependencies: + fill-range: ^7.0.1 + checksum: e2a8e769a863f3d4ee887b5fe21f63193a891c68b612ddb4b68d82d1b5f3ff9073af066c343e9867a393fe4c2555dcb33e89b937195feb9c1613d259edfcd459 + languageName: node + linkType: hard + +"browser-process-hrtime@npm:^1.0.0": + version: 1.0.0 + resolution: "browser-process-hrtime@npm:1.0.0" + checksum: e30f868cdb770b1201afb714ad1575dd86366b6e861900884665fb627109b3cc757c40067d3bfee1ff2a29c835257ea30725a8018a9afd02ac1c24b408b1e45f + languageName: node + linkType: hard + +"browserslist@npm:^4.21.10": + version: 4.22.1 + resolution: "browserslist@npm:4.22.1" + dependencies: + caniuse-lite: ^1.0.30001541 + electron-to-chromium: ^1.4.535 + node-releases: ^2.0.13 + update-browserslist-db: ^1.0.13 + bin: + browserslist: cli.js + checksum: 7e6b10c53f7dd5d83fd2b95b00518889096382539fed6403829d447e05df4744088de46a571071afb447046abc3c66ad06fbc790e70234ec2517452e32ffd862 + languageName: node + linkType: hard + +"cacache@npm:^17.0.0": + version: 17.1.4 + resolution: "cacache@npm:17.1.4" + dependencies: + "@npmcli/fs": ^3.1.0 + fs-minipass: ^3.0.0 + glob: ^10.2.2 + lru-cache: ^7.7.1 + minipass: ^7.0.3 + minipass-collect: ^1.0.2 + minipass-flush: ^1.0.5 + minipass-pipeline: ^1.2.4 + p-map: ^4.0.0 + ssri: ^10.0.0 + tar: ^6.1.11 + unique-filename: ^3.0.0 + checksum: b7751df756656954a51201335addced8f63fc53266fa56392c9f5ae83c8d27debffb4458ac2d168a744a4517ec3f2163af05c20097f93d17bdc2dc8a385e14a6 + languageName: node + linkType: hard + +"caniuse-lite@npm:^1.0.30001538, caniuse-lite@npm:^1.0.30001541": + version: 1.0.30001546 + resolution: "caniuse-lite@npm:1.0.30001546" + checksum: d3ef82f5ee94743002c5b2dd61c84342debcc94b2d5907b64ade3514ecfc4f20bbe86a6bc453fd6436d5fbcf6582e07405d7c2077565675a71c83adc238a11fa + languageName: node + linkType: hard + +"chalk@npm:^4.1.2": + version: 4.1.2 + resolution: "chalk@npm:4.1.2" + dependencies: + ansi-styles: ^4.1.0 + supports-color: ^7.1.0 + checksum: fe75c9d5c76a7a98d45495b91b2172fa3b7a09e0cc9370e5c8feb1c567b85c4288e2b3fded7cfdd7359ac28d6b3844feb8b82b8686842e93d23c827c417e83fc + languageName: node + linkType: hard + +"cheerio-select@npm:^2.1.0": + version: 2.1.0 + resolution: "cheerio-select@npm:2.1.0" + dependencies: + boolbase: ^1.0.0 + css-select: ^5.1.0 + css-what: ^6.1.0 + domelementtype: ^2.3.0 + domhandler: ^5.0.3 + domutils: ^3.0.1 + checksum: 843d6d479922f28a6c5342c935aff1347491156814de63c585a6eb73baf7bb4185c1b4383a1195dca0f12e3946d737c7763bcef0b9544c515d905c5c44c5308b + languageName: node + linkType: hard + +"cheerio@npm:^1.0.0-rc.12": + version: 1.0.0-rc.12 + resolution: "cheerio@npm:1.0.0-rc.12" + dependencies: + cheerio-select: ^2.1.0 + dom-serializer: ^2.0.0 + domhandler: ^5.0.3 + domutils: ^3.0.1 + htmlparser2: ^8.0.1 + parse5: ^7.0.0 + parse5-htmlparser2-tree-adapter: ^7.0.0 + checksum: 5d4c1b7a53cf22d3a2eddc0aff70cf23cbb30d01a4c79013e703a012475c02461aa1fcd99127e8d83a02216386ed6942b2c8103845fd0812300dd199e6e7e054 + languageName: node + linkType: hard + +"chokidar@npm:>=3.0.0 <4.0.0": + version: 3.5.3 + resolution: "chokidar@npm:3.5.3" + dependencies: + anymatch: ~3.1.2 + braces: ~3.0.2 + fsevents: ~2.3.2 + glob-parent: ~5.1.2 + is-binary-path: ~2.1.0 + is-glob: ~4.0.1 + normalize-path: ~3.0.0 + readdirp: ~3.6.0 + dependenciesMeta: + fsevents: + optional: true + checksum: b49fcde40176ba007ff361b198a2d35df60d9bb2a5aab228279eb810feae9294a6b4649ab15981304447afe1e6ffbf4788ad5db77235dc770ab777c6e771980c + languageName: node + linkType: hard + +"chownr@npm:^2.0.0": + version: 2.0.0 + resolution: "chownr@npm:2.0.0" + checksum: c57cf9dd0791e2f18a5ee9c1a299ae6e801ff58fee96dc8bfd0dcb4738a6ce58dd252a3605b1c93c6418fe4f9d5093b28ffbf4d66648cb2a9c67eaef9679be2f + languageName: node + linkType: hard + +"clean-stack@npm:^2.0.0": + version: 2.2.0 + resolution: "clean-stack@npm:2.2.0" + checksum: 2ac8cd2b2f5ec986a3c743935ec85b07bc174d5421a5efc8017e1f146a1cf5f781ae962618f416352103b32c9cd7e203276e8c28241bbe946160cab16149fb68 + languageName: node + linkType: hard + +"color-convert@npm:^2.0.1": + version: 2.0.1 + resolution: "color-convert@npm:2.0.1" + dependencies: + color-name: ~1.1.4 + checksum: 79e6bdb9fd479a205c71d89574fccfb22bd9053bd98c6c4d870d65c132e5e904e6034978e55b43d69fcaa7433af2016ee203ce76eeba9cfa554b373e7f7db336 + languageName: node + linkType: hard + +"color-name@npm:~1.1.4": + version: 1.1.4 + resolution: "color-name@npm:1.1.4" + checksum: b0445859521eb4021cd0fb0cc1a75cecf67fceecae89b63f62b201cca8d345baf8b952c966862a9d9a2632987d4f6581f0ec8d957dfacece86f0a7919316f610 + languageName: node + linkType: hard + +"color-support@npm:^1.1.3": + version: 1.1.3 + resolution: "color-support@npm:1.1.3" + bin: + color-support: bin.js + checksum: 9b7356817670b9a13a26ca5af1c21615463b500783b739b7634a0c2047c16cef4b2865d7576875c31c3cddf9dd621fa19285e628f20198b233a5cfdda6d0793b + languageName: node + linkType: hard + +"combined-stream@npm:^1.0.8": + version: 1.0.8 + resolution: "combined-stream@npm:1.0.8" + dependencies: + delayed-stream: ~1.0.0 + checksum: 49fa4aeb4916567e33ea81d088f6584749fc90c7abec76fd516bf1c5aa5c79f3584b5ba3de6b86d26ddd64bae5329c4c7479343250cfe71c75bb366eae53bb7c + languageName: node + linkType: hard + +"concat-map@npm:0.0.1": + version: 0.0.1 + resolution: "concat-map@npm:0.0.1" + checksum: 902a9f5d8967a3e2faf138d5cb784b9979bad2e6db5357c5b21c568df4ebe62bcb15108af1b2253744844eb964fc023fbd9afbbbb6ddd0bcc204c6fb5b7bf3af + languageName: node + linkType: hard + +"console-control-strings@npm:^1.1.0": + version: 1.1.0 + resolution: "console-control-strings@npm:1.1.0" + checksum: 8755d76787f94e6cf79ce4666f0c5519906d7f5b02d4b884cf41e11dcd759ed69c57da0670afd9236d229a46e0f9cf519db0cd829c6dca820bb5a5c3def584ed + languageName: node + linkType: hard + +"cross-spawn@npm:^7.0.0": + version: 7.0.3 + resolution: "cross-spawn@npm:7.0.3" + dependencies: + path-key: ^3.1.0 + shebang-command: ^2.0.0 + which: ^2.0.1 + checksum: 671cc7c7288c3a8406f3c69a3ae2fc85555c04169e9d611def9a675635472614f1c0ed0ef80955d5b6d4e724f6ced67f0ad1bb006c2ea643488fcfef994d7f52 + languageName: node + linkType: hard + +"css-select@npm:^5.1.0": + version: 5.1.0 + resolution: "css-select@npm:5.1.0" + dependencies: + boolbase: ^1.0.0 + css-what: ^6.1.0 + domhandler: ^5.0.2 + domutils: ^3.0.1 + nth-check: ^2.0.1 + checksum: 2772c049b188d3b8a8159907192e926e11824aea525b8282981f72ba3f349cf9ecd523fdf7734875ee2cb772246c22117fc062da105b6d59afe8dcd5c99c9bda + languageName: node + linkType: hard + +"css-what@npm:^6.1.0": + version: 6.1.0 + resolution: "css-what@npm:6.1.0" + checksum: b975e547e1e90b79625918f84e67db5d33d896e6de846c9b584094e529f0c63e2ab85ee33b9daffd05bff3a146a1916bec664e18bb76dd5f66cbff9fc13b2bbe + languageName: node + linkType: hard + +"cssom@npm:^0.5.0": + version: 0.5.0 + resolution: "cssom@npm:0.5.0" + checksum: 823471aa30091c59e0a305927c30e7768939b6af70405808f8d2ce1ca778cddcb24722717392438329d1691f9a87cb0183b64b8d779b56a961546d54854fde01 + languageName: node + linkType: hard + +"cssom@npm:~0.3.6": + version: 0.3.8 + resolution: "cssom@npm:0.3.8" + checksum: 24beb3087c76c0d52dd458be9ee1fbc80ac771478a9baef35dd258cdeb527c68eb43204dd439692bb2b1ae5272fa5f2946d10946edab0d04f1078f85e06bc7f6 + languageName: node + linkType: hard + +"cssstyle@npm:^2.3.0": + version: 2.3.0 + resolution: "cssstyle@npm:2.3.0" + dependencies: + cssom: ~0.3.6 + checksum: 5f05e6fd2e3df0b44695c2f08b9ef38b011862b274e320665176467c0725e44a53e341bc4959a41176e83b66064ab786262e7380fd1cabeae6efee0d255bb4e3 + languageName: node + linkType: hard + +"data-urls@npm:^3.0.0": + version: 3.0.2 + resolution: "data-urls@npm:3.0.2" + dependencies: + abab: ^2.0.6 + whatwg-mimetype: ^3.0.0 + whatwg-url: ^11.0.0 + checksum: 033fc3dd0fba6d24bc9a024ddcf9923691dd24f90a3d26f6545d6a2f71ec6956f93462f2cdf2183cc46f10dc01ed3bcb36731a8208456eb1a08147e571fe2a76 + languageName: node + linkType: hard + +"data@workspace:.": + version: 0.0.0-use.local + resolution: "data@workspace:." + dependencies: + "@chialab/esbuild-plugin-html": ^0.17.2 + "@craftamap/esbuild-plugin-html": ^0.5.0 + "@esbuilder/html": ^0.0.6 + autoprefixer: ^10.4.16 + bootstrap: ^5.3.2 + esbuild: 0.19.4 + esbuild-plugin-clean: ^1.0.1 + esbuild-plugin-handlebars: ^1.0.2 + esbuild-sass-plugin: ^2.16.0 + handlebars: ^4.7.7 + postcss: ^8.4.31 + typescript: ^5.1.6 + languageName: unknown + linkType: soft + +"debug@npm:4, debug@npm:^4.3.3": + version: 4.3.4 + resolution: "debug@npm:4.3.4" + dependencies: + ms: 2.1.2 + peerDependenciesMeta: + supports-color: + optional: true + checksum: 3dbad3f94ea64f34431a9cbf0bafb61853eda57bff2880036153438f50fb5a84f27683ba0d8e5426bf41a8c6ff03879488120cf5b3a761e77953169c0600a708 + languageName: node + linkType: hard + +"decimal.js@npm:^10.3.1": + version: 10.4.3 + resolution: "decimal.js@npm:10.4.3" + checksum: 796404dcfa9d1dbfdc48870229d57f788b48c21c603c3f6554a1c17c10195fc1024de338b0cf9e1efe0c7c167eeb18f04548979bcc5fdfabebb7cc0ae3287bae + languageName: node + linkType: hard + +"del@npm:^6.0.0": + version: 6.1.1 + resolution: "del@npm:6.1.1" + dependencies: + globby: ^11.0.1 + graceful-fs: ^4.2.4 + is-glob: ^4.0.1 + is-path-cwd: ^2.2.0 + is-path-inside: ^3.0.2 + p-map: ^4.0.0 + rimraf: ^3.0.2 + slash: ^3.0.0 + checksum: 563288b73b8b19a7261c47fd21a330eeab6e2acd7c6208c49790dfd369127120dd7836cdf0c1eca216b77c94782a81507eac6b4734252d3bef2795cb366996b6 + languageName: node + linkType: hard + +"delayed-stream@npm:~1.0.0": + version: 1.0.0 + resolution: "delayed-stream@npm:1.0.0" + checksum: 46fe6e83e2cb1d85ba50bd52803c68be9bd953282fa7096f51fc29edd5d67ff84ff753c51966061e5ba7cb5e47ef6d36a91924eddb7f3f3483b1c560f77a0020 + languageName: node + linkType: hard + +"delegates@npm:^1.0.0": + version: 1.0.0 + resolution: "delegates@npm:1.0.0" + checksum: a51744d9b53c164ba9c0492471a1a2ffa0b6727451bdc89e31627fdf4adda9d51277cfcbfb20f0a6f08ccb3c436f341df3e92631a3440226d93a8971724771fd + languageName: node + linkType: hard + +"detect-libc@npm:^1.0.3": + version: 1.0.3 + resolution: "detect-libc@npm:1.0.3" + bin: + detect-libc: ./bin/detect-libc.js + checksum: daaaed925ffa7889bd91d56e9624e6c8033911bb60f3a50a74a87500680652969dbaab9526d1e200a4c94acf80fc862a22131841145a0a8482d60a99c24f4a3e + languageName: node + linkType: hard + +"dir-glob@npm:^3.0.1": + version: 3.0.1 + resolution: "dir-glob@npm:3.0.1" + dependencies: + path-type: ^4.0.0 + checksum: fa05e18324510d7283f55862f3161c6759a3f2f8dbce491a2fc14c8324c498286c54282c1f0e933cb930da8419b30679389499b919122952a4f8592362ef4615 + languageName: node + linkType: hard + +"dom-serializer@npm:^2.0.0": + version: 2.0.0 + resolution: "dom-serializer@npm:2.0.0" + dependencies: + domelementtype: ^2.3.0 + domhandler: ^5.0.2 + entities: ^4.2.0 + checksum: cd1810544fd8cdfbd51fa2c0c1128ec3a13ba92f14e61b7650b5de421b88205fd2e3f0cc6ace82f13334114addb90ed1c2f23074a51770a8e9c1273acbc7f3e6 + languageName: node + linkType: hard + +"domelementtype@npm:^2.3.0": + version: 2.3.0 + resolution: "domelementtype@npm:2.3.0" + checksum: ee837a318ff702622f383409d1f5b25dd1024b692ef64d3096ff702e26339f8e345820f29a68bcdcea8cfee3531776b3382651232fbeae95612d6f0a75efb4f6 + languageName: node + linkType: hard + +"domexception@npm:^2.0.1": + version: 2.0.1 + resolution: "domexception@npm:2.0.1" + dependencies: + webidl-conversions: ^5.0.0 + checksum: d638e9cb05c52999f1b2eb87c374b03311ea5b1d69c2f875bc92da73e17db60c12142b45c950228642ff7f845c536b65305483350d080df59003a653da80b691 + languageName: node + linkType: hard + +"domhandler@npm:^5.0.2, domhandler@npm:^5.0.3": + version: 5.0.3 + resolution: "domhandler@npm:5.0.3" + dependencies: + domelementtype: ^2.3.0 + checksum: 0f58f4a6af63e6f3a4320aa446d28b5790a009018707bce2859dcb1d21144c7876482b5188395a188dfa974238c019e0a1e610d2fc269a12b2c192ea2b0b131c + languageName: node + linkType: hard + +"domutils@npm:^3.0.1": + version: 3.1.0 + resolution: "domutils@npm:3.1.0" + dependencies: + dom-serializer: ^2.0.0 + domelementtype: ^2.3.0 + domhandler: ^5.0.3 + checksum: e5757456ddd173caa411cfc02c2bb64133c65546d2c4081381a3bafc8a57411a41eed70494551aa58030be9e58574fcc489828bebd673863d39924fb4878f416 + languageName: node + linkType: hard + +"eastasianwidth@npm:^0.2.0": + version: 0.2.0 + resolution: "eastasianwidth@npm:0.2.0" + checksum: 7d00d7cd8e49b9afa762a813faac332dee781932d6f2c848dc348939c4253f1d4564341b7af1d041853bc3f32c2ef141b58e0a4d9862c17a7f08f68df1e0f1ed + languageName: node + linkType: hard + +"electron-to-chromium@npm:^1.4.535": + version: 1.4.544 + resolution: "electron-to-chromium@npm:1.4.544" + checksum: 78e88e4c56fc4faaa9a405de5e0b51305531e9cdf2c71bcc9296c2c59fb68001472e5b924f8701c873bc855ab5174cf0340642712d7af05c1d8e92356529397e + languageName: node + linkType: hard + +"emoji-regex@npm:^8.0.0": + version: 8.0.0 + resolution: "emoji-regex@npm:8.0.0" + checksum: d4c5c39d5a9868b5fa152f00cada8a936868fd3367f33f71be515ecee4c803132d11b31a6222b2571b1e5f7e13890156a94880345594d0ce7e3c9895f560f192 + languageName: node + linkType: hard + +"emoji-regex@npm:^9.2.2": + version: 9.2.2 + resolution: "emoji-regex@npm:9.2.2" + checksum: 8487182da74aabd810ac6d6f1994111dfc0e331b01271ae01ec1eb0ad7b5ecc2bbbbd2f053c05cb55a1ac30449527d819bbfbf0e3de1023db308cbcb47f86601 + languageName: node + linkType: hard + +"encoding@npm:^0.1.13": + version: 0.1.13 + resolution: "encoding@npm:0.1.13" + dependencies: + iconv-lite: ^0.6.2 + checksum: bb98632f8ffa823996e508ce6a58ffcf5856330fde839ae42c9e1f436cc3b5cc651d4aeae72222916545428e54fd0f6aa8862fd8d25bdbcc4589f1e3f3715e7f + languageName: node + linkType: hard + +"entities@npm:^4.2.0, entities@npm:^4.4.0": + version: 4.5.0 + resolution: "entities@npm:4.5.0" + checksum: 853f8ebd5b425d350bffa97dd6958143179a5938352ccae092c62d1267c4e392a039be1bae7d51b6e4ffad25f51f9617531fedf5237f15df302ccfb452cbf2d7 + languageName: node + linkType: hard + +"env-paths@npm:^2.2.0": + version: 2.2.1 + resolution: "env-paths@npm:2.2.1" + checksum: 65b5df55a8bab92229ab2b40dad3b387fad24613263d103a97f91c9fe43ceb21965cd3392b1ccb5d77088021e525c4e0481adb309625d0cb94ade1d1fb8dc17e + languageName: node + linkType: hard + +"err-code@npm:^2.0.2": + version: 2.0.3 + resolution: "err-code@npm:2.0.3" + checksum: 8b7b1be20d2de12d2255c0bc2ca638b7af5171142693299416e6a9339bd7d88fc8d7707d913d78e0993176005405a236b066b45666b27b797252c771156ace54 + languageName: node + linkType: hard + +"esbuild-plugin-clean@npm:^1.0.1": + version: 1.0.1 + resolution: "esbuild-plugin-clean@npm:1.0.1" + dependencies: + chalk: ^4.1.2 + del: ^6.0.0 + peerDependencies: + esbuild: ">= 0.14.0" + checksum: f2213ee2cb77b8e26ed1e3e5ee9792ff389656c9dec829b990c59eaeade38b17153b7b118e8214ccc8c2f93a5ec17f7ab780630b3535a461c41434fde1cec6ff + languageName: node + linkType: hard + +"esbuild-plugin-handlebars@npm:^1.0.2": + version: 1.0.2 + resolution: "esbuild-plugin-handlebars@npm:1.0.2" + dependencies: + handlebars: ^4.7.7 + checksum: d5e46a28bf57e68cfc7353060fd10dfe4861d2605da7e50d82a7d790d55de42e11cd9058eb887c5ddbbba0f199efbc64d0f3819d552db0b949d2e0c63fe0ad95 + languageName: node + linkType: hard + +"esbuild-sass-plugin@npm:^2.16.0": + version: 2.16.0 + resolution: "esbuild-sass-plugin@npm:2.16.0" + dependencies: + resolve: ^1.22.6 + sass: ^1.7.3 + peerDependencies: + esbuild: ^0.19.4 + checksum: 07824577d2336ea1dc1e5eb27647fc6a54c19ec0dc81ad408d322bf3629bd2344fb69691a9c9c77c5f573f64dccf0ada3dd7c0af1bef9490404bb3d74d6fc8fa + languageName: node + linkType: hard + +"esbuild@npm:0.19.4": + version: 0.19.4 + resolution: "esbuild@npm:0.19.4" + dependencies: + "@esbuild/android-arm": 0.19.4 + "@esbuild/android-arm64": 0.19.4 + "@esbuild/android-x64": 0.19.4 + "@esbuild/darwin-arm64": 0.19.4 + "@esbuild/darwin-x64": 0.19.4 + "@esbuild/freebsd-arm64": 0.19.4 + "@esbuild/freebsd-x64": 0.19.4 + "@esbuild/linux-arm": 0.19.4 + "@esbuild/linux-arm64": 0.19.4 + "@esbuild/linux-ia32": 0.19.4 + "@esbuild/linux-loong64": 0.19.4 + "@esbuild/linux-mips64el": 0.19.4 + "@esbuild/linux-ppc64": 0.19.4 + "@esbuild/linux-riscv64": 0.19.4 + "@esbuild/linux-s390x": 0.19.4 + "@esbuild/linux-x64": 0.19.4 + "@esbuild/netbsd-x64": 0.19.4 + "@esbuild/openbsd-x64": 0.19.4 + "@esbuild/sunos-x64": 0.19.4 + "@esbuild/win32-arm64": 0.19.4 + "@esbuild/win32-ia32": 0.19.4 + "@esbuild/win32-x64": 0.19.4 + dependenciesMeta: + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 024309a16365b020815a30e9a3a9354894a391cf1adbfad7f44a975cf161ab5e961619b30e1ec8ea02994631d71e6b38831119be69f8ccb610c32bbe21addc79 + languageName: node + linkType: hard + +"escalade@npm:^3.1.1": + version: 3.1.1 + resolution: "escalade@npm:3.1.1" + checksum: a3e2a99f07acb74b3ad4989c48ca0c3140f69f923e56d0cba0526240ee470b91010f9d39001f2a4a313841d237ede70a729e92125191ba5d21e74b106800b133 + languageName: node + linkType: hard + +"escodegen@npm:^2.0.0": + version: 2.1.0 + resolution: "escodegen@npm:2.1.0" + dependencies: + esprima: ^4.0.1 + estraverse: ^5.2.0 + esutils: ^2.0.2 + source-map: ~0.6.1 + dependenciesMeta: + source-map: + optional: true + bin: + escodegen: bin/escodegen.js + esgenerate: bin/esgenerate.js + checksum: 096696407e161305cd05aebb95134ad176708bc5cb13d0dcc89a5fcbb959b8ed757e7f2591a5f8036f8f4952d4a724de0df14cd419e29212729fa6df5ce16bf6 + languageName: node + linkType: hard + +"esprima@npm:^4.0.1": + version: 4.0.1 + resolution: "esprima@npm:4.0.1" + bin: + esparse: ./bin/esparse.js + esvalidate: ./bin/esvalidate.js + checksum: b45bc805a613dbea2835278c306b91aff6173c8d034223fa81498c77dcbce3b2931bf6006db816f62eacd9fd4ea975dfd85a5b7f3c6402cfd050d4ca3c13a628 + languageName: node + linkType: hard + +"estraverse@npm:^5.2.0": + version: 5.3.0 + resolution: "estraverse@npm:5.3.0" + checksum: 072780882dc8416ad144f8fe199628d2b3e7bbc9989d9ed43795d2c90309a2047e6bc5979d7e2322a341163d22cfad9e21f4110597fe487519697389497e4e2b + languageName: node + linkType: hard + +"esutils@npm:^2.0.2": + version: 2.0.3 + resolution: "esutils@npm:2.0.3" + checksum: 22b5b08f74737379a840b8ed2036a5fb35826c709ab000683b092d9054e5c2a82c27818f12604bfc2a9a76b90b6834ef081edbc1c7ae30d1627012e067c6ec87 + languageName: node + linkType: hard + +"exponential-backoff@npm:^3.1.1": + version: 3.1.1 + resolution: "exponential-backoff@npm:3.1.1" + checksum: 3d21519a4f8207c99f7457287291316306255a328770d320b401114ec8481986e4e467e854cb9914dd965e0a1ca810a23ccb559c642c88f4c7f55c55778a9b48 + languageName: node + linkType: hard + +"fast-glob@npm:^3.2.9": + version: 3.3.0 + resolution: "fast-glob@npm:3.3.0" + dependencies: + "@nodelib/fs.stat": ^2.0.2 + "@nodelib/fs.walk": ^1.2.3 + glob-parent: ^5.1.2 + merge2: ^1.3.0 + micromatch: ^4.0.4 + checksum: 20df62be28eb5426fe8e40e0d05601a63b1daceb7c3d87534afcad91bdcf1e4b1743cf2d5247d6e225b120b46df0b9053a032b2691ba34ee121e033acd81f547 + languageName: node + linkType: hard + +"fastq@npm:^1.6.0": + version: 1.15.0 + resolution: "fastq@npm:1.15.0" + dependencies: + reusify: ^1.0.4 + checksum: 0170e6bfcd5d57a70412440b8ef600da6de3b2a6c5966aeaf0a852d542daff506a0ee92d6de7679d1de82e644bce69d7a574a6c93f0b03964b5337eed75ada1a + languageName: node + linkType: hard + +"fill-range@npm:^7.0.1": + version: 7.0.1 + resolution: "fill-range@npm:7.0.1" + dependencies: + to-regex-range: ^5.0.1 + checksum: cc283f4e65b504259e64fd969bcf4def4eb08d85565e906b7d36516e87819db52029a76b6363d0f02d0d532f0033c9603b9e2d943d56ee3b0d4f7ad3328ff917 + languageName: node + linkType: hard + +"foreground-child@npm:^3.1.0": + version: 3.1.1 + resolution: "foreground-child@npm:3.1.1" + dependencies: + cross-spawn: ^7.0.0 + signal-exit: ^4.0.1 + checksum: 139d270bc82dc9e6f8bc045fe2aae4001dc2472157044fdfad376d0a3457f77857fa883c1c8b21b491c6caade9a926a4bed3d3d2e8d3c9202b151a4cbbd0bcd5 + languageName: node + linkType: hard + +"form-data@npm:^4.0.0": + version: 4.0.0 + resolution: "form-data@npm:4.0.0" + dependencies: + asynckit: ^0.4.0 + combined-stream: ^1.0.8 + mime-types: ^2.1.12 + checksum: 01135bf8675f9d5c61ff18e2e2932f719ca4de964e3be90ef4c36aacfc7b9cb2fceb5eca0b7e0190e3383fe51c5b37f4cb80b62ca06a99aaabfcfd6ac7c9328c + languageName: node + linkType: hard + +"fraction.js@npm:^4.3.6": + version: 4.3.6 + resolution: "fraction.js@npm:4.3.6" + checksum: e96ae77e64ebfd442d3a5a01a3f0637b0663fc2440bcf2841b3ad9341ba24c81fb2e3e7142e43ef7d088558c6b3f8609df135b201adc7a1c674aea6a71384162 + languageName: node + linkType: hard + +"fs-minipass@npm:^2.0.0": + version: 2.1.0 + resolution: "fs-minipass@npm:2.1.0" + dependencies: + minipass: ^3.0.0 + checksum: 1b8d128dae2ac6cc94230cc5ead341ba3e0efaef82dab46a33d171c044caaa6ca001364178d42069b2809c35a1c3c35079a32107c770e9ffab3901b59af8c8b1 + languageName: node + linkType: hard + +"fs-minipass@npm:^3.0.0": + version: 3.0.3 + resolution: "fs-minipass@npm:3.0.3" + dependencies: + minipass: ^7.0.3 + checksum: 8722a41109130851d979222d3ec88aabaceeaaf8f57b2a8f744ef8bd2d1ce95453b04a61daa0078822bc5cd21e008814f06fe6586f56fef511e71b8d2394d802 + languageName: node + linkType: hard + +"fs.realpath@npm:^1.0.0": + version: 1.0.0 + resolution: "fs.realpath@npm:1.0.0" + checksum: 99ddea01a7e75aa276c250a04eedeffe5662bce66c65c07164ad6264f9de18fb21be9433ead460e54cff20e31721c811f4fb5d70591799df5f85dce6d6746fd0 + languageName: node + linkType: hard + +"fsevents@npm:~2.3.2": + version: 2.3.2 + resolution: "fsevents@npm:2.3.2" + dependencies: + node-gyp: latest + checksum: 97ade64e75091afee5265e6956cb72ba34db7819b4c3e94c431d4be2b19b8bb7a2d4116da417950c3425f17c8fe693d25e20212cac583ac1521ad066b77ae31f + conditions: os=darwin + languageName: node + linkType: hard + +"fsevents@patch:fsevents@~2.3.2#~builtin": + version: 2.3.2 + resolution: "fsevents@patch:fsevents@npm%3A2.3.2#~builtin::version=2.3.2&hash=18f3a7" + dependencies: + node-gyp: latest + conditions: os=darwin + languageName: node + linkType: hard + +"function-bind@npm:^1.1.1": + version: 1.1.1 + resolution: "function-bind@npm:1.1.1" + checksum: b32fbaebb3f8ec4969f033073b43f5c8befbb58f1a79e12f1d7490358150359ebd92f49e72ff0144f65f2c48ea2a605bff2d07965f548f6474fd8efd95bf361a + languageName: node + linkType: hard + +"gauge@npm:^4.0.3": + version: 4.0.4 + resolution: "gauge@npm:4.0.4" + dependencies: + aproba: ^1.0.3 || ^2.0.0 + color-support: ^1.1.3 + console-control-strings: ^1.1.0 + has-unicode: ^2.0.1 + signal-exit: ^3.0.7 + string-width: ^4.2.3 + strip-ansi: ^6.0.1 + wide-align: ^1.1.5 + checksum: 788b6bfe52f1dd8e263cda800c26ac0ca2ff6de0b6eee2fe0d9e3abf15e149b651bd27bf5226be10e6e3edb5c4e5d5985a5a1a98137e7a892f75eff76467ad2d + languageName: node + linkType: hard + +"glob-parent@npm:^5.1.2, glob-parent@npm:~5.1.2": + version: 5.1.2 + resolution: "glob-parent@npm:5.1.2" + dependencies: + is-glob: ^4.0.1 + checksum: f4f2bfe2425296e8a47e36864e4f42be38a996db40420fe434565e4480e3322f18eb37589617a98640c5dc8fdec1a387007ee18dbb1f3f5553409c34d17f425e + languageName: node + linkType: hard + +"glob@npm:^10.2.2": + version: 10.3.3 + resolution: "glob@npm:10.3.3" + dependencies: + foreground-child: ^3.1.0 + jackspeak: ^2.0.3 + minimatch: ^9.0.1 + minipass: ^5.0.0 || ^6.0.2 || ^7.0.0 + path-scurry: ^1.10.1 + bin: + glob: dist/cjs/src/bin.js + checksum: 29190d3291f422da0cb40b77a72fc8d2c51a36524e99b8bf412548b7676a6627489528b57250429612b6eec2e6fe7826d328451d3e694a9d15e575389308ec53 + languageName: node + linkType: hard + +"glob@npm:^7.1.3, glob@npm:^7.1.4": + version: 7.2.3 + resolution: "glob@npm:7.2.3" + dependencies: + fs.realpath: ^1.0.0 + inflight: ^1.0.4 + inherits: 2 + minimatch: ^3.1.1 + once: ^1.3.0 + path-is-absolute: ^1.0.0 + checksum: 29452e97b38fa704dabb1d1045350fb2467cf0277e155aa9ff7077e90ad81d1ea9d53d3ee63bd37c05b09a065e90f16aec4a65f5b8de401d1dac40bc5605d133 + languageName: node + linkType: hard + +"globby@npm:^11.0.1": + version: 11.1.0 + resolution: "globby@npm:11.1.0" + dependencies: + array-union: ^2.1.0 + dir-glob: ^3.0.1 + fast-glob: ^3.2.9 + ignore: ^5.2.0 + merge2: ^1.4.1 + slash: ^3.0.0 + checksum: b4be8885e0cfa018fc783792942d53926c35c50b3aefd3fdcfb9d22c627639dc26bd2327a40a0b74b074100ce95bb7187bfeae2f236856aa3de183af7a02aea6 + languageName: node + linkType: hard + +"graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6": + version: 4.2.11 + resolution: "graceful-fs@npm:4.2.11" + checksum: ac85f94da92d8eb6b7f5a8b20ce65e43d66761c55ce85ac96df6865308390da45a8d3f0296dd3a663de65d30ba497bd46c696cc1e248c72b13d6d567138a4fc7 + languageName: node + linkType: hard + +"handlebars@npm:^4.7.7": + version: 4.7.7 + resolution: "handlebars@npm:4.7.7" + dependencies: + minimist: ^1.2.5 + neo-async: ^2.6.0 + source-map: ^0.6.1 + uglify-js: ^3.1.4 + wordwrap: ^1.0.0 + dependenciesMeta: + uglify-js: + optional: true + bin: + handlebars: bin/handlebars + checksum: 1e79a43f5e18d15742977cb987923eab3e2a8f44f2d9d340982bcb69e1735ed049226e534d7c1074eaddaf37e4fb4f471a8adb71cddd5bc8cf3f894241df5cee + languageName: node + linkType: hard + +"has-flag@npm:^4.0.0": + version: 4.0.0 + resolution: "has-flag@npm:4.0.0" + checksum: 261a1357037ead75e338156b1f9452c016a37dcd3283a972a30d9e4a87441ba372c8b81f818cd0fbcd9c0354b4ae7e18b9e1afa1971164aef6d18c2b6095a8ad + languageName: node + linkType: hard + +"has-unicode@npm:^2.0.1": + version: 2.0.1 + resolution: "has-unicode@npm:2.0.1" + checksum: 1eab07a7436512db0be40a710b29b5dc21fa04880b7f63c9980b706683127e3c1b57cb80ea96d47991bdae2dfe479604f6a1ba410106ee1046a41d1bd0814400 + languageName: node + linkType: hard + +"has@npm:^1.0.3": + version: 1.0.3 + resolution: "has@npm:1.0.3" + dependencies: + function-bind: ^1.1.1 + checksum: b9ad53d53be4af90ce5d1c38331e712522417d017d5ef1ebd0507e07c2fbad8686fffb8e12ddecd4c39ca9b9b47431afbb975b8abf7f3c3b82c98e9aad052792 + languageName: node + linkType: hard + +"html-encoding-sniffer@npm:^2.0.1": + version: 2.0.1 + resolution: "html-encoding-sniffer@npm:2.0.1" + dependencies: + whatwg-encoding: ^1.0.5 + checksum: bf30cce461015ed7e365736fcd6a3063c7bc016a91f74398ef6158886970a96333938f7c02417ab3c12aa82e3e53b40822145facccb9ddfbcdc15a879ae4d7ba + languageName: node + linkType: hard + +"htmlparser2@npm:^8.0.1": + version: 8.0.2 + resolution: "htmlparser2@npm:8.0.2" + dependencies: + domelementtype: ^2.3.0 + domhandler: ^5.0.3 + domutils: ^3.0.1 + entities: ^4.4.0 + checksum: 29167a0f9282f181da8a6d0311b76820c8a59bc9e3c87009e21968264c2987d2723d6fde5a964d4b7b6cba663fca96ffb373c06d8223a85f52a6089ced942700 + languageName: node + linkType: hard + +"http-cache-semantics@npm:^4.1.1": + version: 4.1.1 + resolution: "http-cache-semantics@npm:4.1.1" + checksum: 83ac0bc60b17a3a36f9953e7be55e5c8f41acc61b22583060e8dedc9dd5e3607c823a88d0926f9150e571f90946835c7fe150732801010845c72cd8bbff1a236 + languageName: node + linkType: hard + +"http-proxy-agent@npm:^4.0.1": + version: 4.0.1 + resolution: "http-proxy-agent@npm:4.0.1" + dependencies: + "@tootallnate/once": 1 + agent-base: 6 + debug: 4 + checksum: c6a5da5a1929416b6bbdf77b1aca13888013fe7eb9d59fc292e25d18e041bb154a8dfada58e223fc7b76b9b2d155a87e92e608235201f77d34aa258707963a82 + languageName: node + linkType: hard + +"http-proxy-agent@npm:^5.0.0": + version: 5.0.0 + resolution: "http-proxy-agent@npm:5.0.0" + dependencies: + "@tootallnate/once": 2 + agent-base: 6 + debug: 4 + checksum: e2ee1ff1656a131953839b2a19cd1f3a52d97c25ba87bd2559af6ae87114abf60971e498021f9b73f9fd78aea8876d1fb0d4656aac8a03c6caa9fc175f22b786 + languageName: node + linkType: hard + +"https-proxy-agent@npm:^5.0.0": + version: 5.0.1 + resolution: "https-proxy-agent@npm:5.0.1" + dependencies: + agent-base: 6 + debug: 4 + checksum: 571fccdf38184f05943e12d37d6ce38197becdd69e58d03f43637f7fa1269cf303a7d228aa27e5b27bbd3af8f09fd938e1c91dcfefff2df7ba77c20ed8dfc765 + languageName: node + linkType: hard + +"humanize-ms@npm:^1.2.1": + version: 1.2.1 + resolution: "humanize-ms@npm:1.2.1" + dependencies: + ms: ^2.0.0 + checksum: 9c7a74a2827f9294c009266c82031030eae811ca87b0da3dceb8d6071b9bde22c9f3daef0469c3c533cc67a97d8a167cd9fc0389350e5f415f61a79b171ded16 + languageName: node + linkType: hard + +"iconv-lite@npm:0.4.24": + version: 0.4.24 + resolution: "iconv-lite@npm:0.4.24" + dependencies: + safer-buffer: ">= 2.1.2 < 3" + checksum: bd9f120f5a5b306f0bc0b9ae1edeb1577161503f5f8252a20f1a9e56ef8775c9959fd01c55f2d3a39d9a8abaf3e30c1abeb1895f367dcbbe0a8fd1c9ca01c4f6 + languageName: node + linkType: hard + +"iconv-lite@npm:^0.6.2": + version: 0.6.3 + resolution: "iconv-lite@npm:0.6.3" + dependencies: + safer-buffer: ">= 2.1.2 < 3.0.0" + checksum: 3f60d47a5c8fc3313317edfd29a00a692cc87a19cac0159e2ce711d0ebc9019064108323b5e493625e25594f11c6236647d8e256fbe7a58f4a3b33b89e6d30bf + languageName: node + linkType: hard + +"ignore@npm:^5.2.0": + version: 5.2.4 + resolution: "ignore@npm:5.2.4" + checksum: 3d4c309c6006e2621659311783eaea7ebcd41fe4ca1d78c91c473157ad6666a57a2df790fe0d07a12300d9aac2888204d7be8d59f9aaf665b1c7fcdb432517ef + languageName: node + linkType: hard + +"immutable@npm:^4.0.0": + version: 4.3.1 + resolution: "immutable@npm:4.3.1" + checksum: a3a5ba29bd43f3f9a2e4d599763d7455d11a0ea57e50bf43f2836672fc80003e90d69f2a4f5b589f1f3d6986faf97f08ce1e253583740dd33c00adebab88b217 + languageName: node + linkType: hard + +"imurmurhash@npm:^0.1.4": + version: 0.1.4 + resolution: "imurmurhash@npm:0.1.4" + checksum: 7cae75c8cd9a50f57dadd77482359f659eaebac0319dd9368bcd1714f55e65badd6929ca58569da2b6494ef13fdd5598cd700b1eba23f8b79c5f19d195a3ecf7 + languageName: node + linkType: hard + +"indent-string@npm:^4.0.0": + version: 4.0.0 + resolution: "indent-string@npm:4.0.0" + checksum: 824cfb9929d031dabf059bebfe08cf3137365e112019086ed3dcff6a0a7b698cb80cf67ccccde0e25b9e2d7527aa6cc1fed1ac490c752162496caba3e6699612 + languageName: node + linkType: hard + +"inflight@npm:^1.0.4": + version: 1.0.6 + resolution: "inflight@npm:1.0.6" + dependencies: + once: ^1.3.0 + wrappy: 1 + checksum: f4f76aa072ce19fae87ce1ef7d221e709afb59d445e05d47fba710e85470923a75de35bfae47da6de1b18afc3ce83d70facf44cfb0aff89f0a3f45c0a0244dfd + languageName: node + linkType: hard + +"inherits@npm:2, inherits@npm:^2.0.3": + version: 2.0.4 + resolution: "inherits@npm:2.0.4" + checksum: 4a48a733847879d6cf6691860a6b1e3f0f4754176e4d71494c41f3475553768b10f84b5ce1d40fbd0e34e6bfbb864ee35858ad4dd2cf31e02fc4a154b724d7f1 + languageName: node + linkType: hard + +"ip@npm:^2.0.0": + version: 2.0.0 + resolution: "ip@npm:2.0.0" + checksum: cfcfac6b873b701996d71ec82a7dd27ba92450afdb421e356f44044ed688df04567344c36cbacea7d01b1c39a4c732dc012570ebe9bebfb06f27314bca625349 + languageName: node + linkType: hard + +"is-binary-path@npm:~2.1.0": + version: 2.1.0 + resolution: "is-binary-path@npm:2.1.0" + dependencies: + binary-extensions: ^2.0.0 + checksum: 84192eb88cff70d320426f35ecd63c3d6d495da9d805b19bc65b518984b7c0760280e57dbf119b7e9be6b161784a5a673ab2c6abe83abb5198a432232ad5b35c + languageName: node + linkType: hard + +"is-core-module@npm:^2.13.0": + version: 2.13.0 + resolution: "is-core-module@npm:2.13.0" + dependencies: + has: ^1.0.3 + checksum: 053ab101fb390bfeb2333360fd131387bed54e476b26860dc7f5a700bbf34a0ec4454f7c8c4d43e8a0030957e4b3db6e16d35e1890ea6fb654c833095e040355 + languageName: node + linkType: hard + +"is-extglob@npm:^2.1.1": + version: 2.1.1 + resolution: "is-extglob@npm:2.1.1" + checksum: df033653d06d0eb567461e58a7a8c9f940bd8c22274b94bf7671ab36df5719791aae15eef6d83bbb5e23283967f2f984b8914559d4449efda578c775c4be6f85 + languageName: node + linkType: hard + +"is-fullwidth-code-point@npm:^3.0.0": + version: 3.0.0 + resolution: "is-fullwidth-code-point@npm:3.0.0" + checksum: 44a30c29457c7fb8f00297bce733f0a64cd22eca270f83e58c105e0d015e45c019491a4ab2faef91ab51d4738c670daff901c799f6a700e27f7314029e99e348 + languageName: node + linkType: hard + +"is-glob@npm:^4.0.1, is-glob@npm:~4.0.1": + version: 4.0.3 + resolution: "is-glob@npm:4.0.3" + dependencies: + is-extglob: ^2.1.1 + checksum: d381c1319fcb69d341cc6e6c7cd588e17cd94722d9a32dbd60660b993c4fb7d0f19438674e68dfec686d09b7c73139c9166b47597f846af387450224a8101ab4 + languageName: node + linkType: hard + +"is-lambda@npm:^1.0.1": + version: 1.0.1 + resolution: "is-lambda@npm:1.0.1" + checksum: 93a32f01940220532e5948538699ad610d5924ac86093fcee83022252b363eb0cc99ba53ab084a04e4fb62bf7b5731f55496257a4c38adf87af9c4d352c71c35 + languageName: node + linkType: hard + +"is-number@npm:^7.0.0": + version: 7.0.0 + resolution: "is-number@npm:7.0.0" + checksum: 456ac6f8e0f3111ed34668a624e45315201dff921e5ac181f8ec24923b99e9f32ca1a194912dc79d539c97d33dba17dc635202ff0b2cf98326f608323276d27a + languageName: node + linkType: hard + +"is-path-cwd@npm:^2.2.0": + version: 2.2.0 + resolution: "is-path-cwd@npm:2.2.0" + checksum: 46a840921bb8cc0dc7b5b423a14220e7db338072a4495743a8230533ce78812dc152548c86f4b828411fe98c5451959f07cf841c6a19f611e46600bd699e8048 + languageName: node + linkType: hard + +"is-path-inside@npm:^3.0.2": + version: 3.0.3 + resolution: "is-path-inside@npm:3.0.3" + checksum: abd50f06186a052b349c15e55b182326f1936c89a78bf6c8f2b707412517c097ce04bc49a0ca221787bc44e1049f51f09a2ffb63d22899051988d3a618ba13e9 + languageName: node + linkType: hard + +"is-potential-custom-element-name@npm:^1.0.1": + version: 1.0.1 + resolution: "is-potential-custom-element-name@npm:1.0.1" + checksum: ced7bbbb6433a5b684af581872afe0e1767e2d1146b2207ca0068a648fb5cab9d898495d1ac0583524faaf24ca98176a7d9876363097c2d14fee6dd324f3a1ab + languageName: node + linkType: hard + +"isexe@npm:^2.0.0": + version: 2.0.0 + resolution: "isexe@npm:2.0.0" + checksum: 26bf6c5480dda5161c820c5b5c751ae1e766c587b1f951ea3fcfc973bafb7831ae5b54a31a69bd670220e42e99ec154475025a468eae58ea262f813fdc8d1c62 + languageName: node + linkType: hard + +"jackspeak@npm:^2.0.3": + version: 2.3.0 + resolution: "jackspeak@npm:2.3.0" + dependencies: + "@isaacs/cliui": ^8.0.2 + "@pkgjs/parseargs": ^0.11.0 + dependenciesMeta: + "@pkgjs/parseargs": + optional: true + checksum: 71bf716f4b5793226d4aeb9761ebf2605ee093b59f91a61451d57d998dd64bbf2b54323fb749b8b2ae8b6d8a463de4f6e3fedab50108671f247bbc80195a6306 + languageName: node + linkType: hard + +"jsdom@npm:^17.0.0": + version: 17.0.0 + resolution: "jsdom@npm:17.0.0" + dependencies: + abab: ^2.0.5 + acorn: ^8.4.1 + acorn-globals: ^6.0.0 + cssom: ^0.5.0 + cssstyle: ^2.3.0 + data-urls: ^3.0.0 + decimal.js: ^10.3.1 + domexception: ^2.0.1 + escodegen: ^2.0.0 + form-data: ^4.0.0 + html-encoding-sniffer: ^2.0.1 + http-proxy-agent: ^4.0.1 + https-proxy-agent: ^5.0.0 + is-potential-custom-element-name: ^1.0.1 + nwsapi: ^2.2.0 + parse5: 6.0.1 + saxes: ^5.0.1 + symbol-tree: ^3.2.4 + tough-cookie: ^4.0.0 + w3c-hr-time: ^1.0.2 + w3c-xmlserializer: ^2.0.0 + webidl-conversions: ^6.1.0 + whatwg-encoding: ^1.0.5 + whatwg-mimetype: ^2.3.0 + whatwg-url: ^9.0.0 + ws: ^8.0.0 + xml-name-validator: ^3.0.0 + peerDependencies: + canvas: ^2.5.0 + peerDependenciesMeta: + canvas: + optional: true + checksum: 4b156517267662b63e43616a03afbbb10c50383e8552d22e695f322ea94b0b33ee61e6401113dd4bacf5b61ac26d94a263296d87cdd8f1a7ab69cf8785f72b88 + languageName: node + linkType: hard + +"lodash._reinterpolate@npm:^3.0.0": + version: 3.0.0 + resolution: "lodash._reinterpolate@npm:3.0.0" + checksum: 06d2d5f33169604fa5e9f27b6067ed9fb85d51a84202a656901e5ffb63b426781a601508466f039c720af111b0c685d12f1a5c14ff8df5d5f27e491e562784b2 + languageName: node + linkType: hard + +"lodash.template@npm:^4.5.0": + version: 4.5.0 + resolution: "lodash.template@npm:4.5.0" + dependencies: + lodash._reinterpolate: ^3.0.0 + lodash.templatesettings: ^4.0.0 + checksum: ca64e5f07b6646c9d3dbc0fe3aaa995cb227c4918abd1cef7a9024cd9c924f2fa389a0ec4296aa6634667e029bc81d4bbdb8efbfde11df76d66085e6c529b450 + languageName: node + linkType: hard + +"lodash.templatesettings@npm:^4.0.0": + version: 4.2.0 + resolution: "lodash.templatesettings@npm:4.2.0" + dependencies: + lodash._reinterpolate: ^3.0.0 + checksum: 863e025478b092997e11a04e9d9e735875eeff1ffcd6c61742aa8272e3c2cddc89ce795eb9726c4e74cef5991f722897ff37df7738a125895f23fc7d12a7bb59 + languageName: node + linkType: hard + +"lru-cache@npm:^6.0.0": + version: 6.0.0 + resolution: "lru-cache@npm:6.0.0" + dependencies: + yallist: ^4.0.0 + checksum: f97f499f898f23e4585742138a22f22526254fdba6d75d41a1c2526b3b6cc5747ef59c5612ba7375f42aca4f8461950e925ba08c991ead0651b4918b7c978297 + languageName: node + linkType: hard + +"lru-cache@npm:^7.7.1": + version: 7.18.3 + resolution: "lru-cache@npm:7.18.3" + checksum: e550d772384709deea3f141af34b6d4fa392e2e418c1498c078de0ee63670f1f46f5eee746e8ef7e69e1c895af0d4224e62ee33e66a543a14763b0f2e74c1356 + languageName: node + linkType: hard + +"lru-cache@npm:^9.1.1 || ^10.0.0": + version: 10.0.1 + resolution: "lru-cache@npm:10.0.1" + checksum: 06f8d0e1ceabd76bb6f644a26dbb0b4c471b79c7b514c13c6856113879b3bf369eb7b497dad4ff2b7e2636db202412394865b33c332100876d838ad1372f0181 + languageName: node + linkType: hard + +"make-fetch-happen@npm:^11.0.3": + version: 11.1.1 + resolution: "make-fetch-happen@npm:11.1.1" + dependencies: + agentkeepalive: ^4.2.1 + cacache: ^17.0.0 + http-cache-semantics: ^4.1.1 + http-proxy-agent: ^5.0.0 + https-proxy-agent: ^5.0.0 + is-lambda: ^1.0.1 + lru-cache: ^7.7.1 + minipass: ^5.0.0 + minipass-fetch: ^3.0.0 + minipass-flush: ^1.0.5 + minipass-pipeline: ^1.2.4 + negotiator: ^0.6.3 + promise-retry: ^2.0.1 + socks-proxy-agent: ^7.0.0 + ssri: ^10.0.0 + checksum: 7268bf274a0f6dcf0343829489a4506603ff34bd0649c12058753900b0eb29191dce5dba12680719a5d0a983d3e57810f594a12f3c18494e93a1fbc6348a4540 + languageName: node + linkType: hard + +"merge2@npm:^1.3.0, merge2@npm:^1.4.1": + version: 1.4.1 + resolution: "merge2@npm:1.4.1" + checksum: 7268db63ed5169466540b6fb947aec313200bcf6d40c5ab722c22e242f651994619bcd85601602972d3c85bd2cc45a358a4c61937e9f11a061919a1da569b0c2 + languageName: node + linkType: hard + +"micromatch@npm:^4.0.4": + version: 4.0.5 + resolution: "micromatch@npm:4.0.5" + dependencies: + braces: ^3.0.2 + picomatch: ^2.3.1 + checksum: 02a17b671c06e8fefeeb6ef996119c1e597c942e632a21ef589154f23898c9c6a9858526246abb14f8bca6e77734aa9dcf65476fca47cedfb80d9577d52843fc + languageName: node + linkType: hard + +"mime-db@npm:1.52.0": + version: 1.52.0 + resolution: "mime-db@npm:1.52.0" + checksum: 0d99a03585f8b39d68182803b12ac601d9c01abfa28ec56204fa330bc9f3d1c5e14beb049bafadb3dbdf646dfb94b87e24d4ec7b31b7279ef906a8ea9b6a513f + languageName: node + linkType: hard + +"mime-types@npm:^2.1.12": + version: 2.1.35 + resolution: "mime-types@npm:2.1.35" + dependencies: + mime-db: 1.52.0 + checksum: 89a5b7f1def9f3af5dad6496c5ed50191ae4331cc5389d7c521c8ad28d5fdad2d06fd81baf38fed813dc4e46bb55c8145bb0ff406330818c9cf712fb2e9b3836 + languageName: node + linkType: hard + +"minimatch@npm:^3.1.1": + version: 3.1.2 + resolution: "minimatch@npm:3.1.2" + dependencies: + brace-expansion: ^1.1.7 + checksum: c154e566406683e7bcb746e000b84d74465b3a832c45d59912b9b55cd50dee66e5c4b1e5566dba26154040e51672f9aa450a9aef0c97cfc7336b78b7afb9540a + languageName: node + linkType: hard + +"minimatch@npm:^9.0.1": + version: 9.0.3 + resolution: "minimatch@npm:9.0.3" + dependencies: + brace-expansion: ^2.0.1 + checksum: 253487976bf485b612f16bf57463520a14f512662e592e95c571afdab1442a6a6864b6c88f248ce6fc4ff0b6de04ac7aa6c8bb51e868e99d1d65eb0658a708b5 + languageName: node + linkType: hard + +"minimist@npm:^1.2.5": + version: 1.2.8 + resolution: "minimist@npm:1.2.8" + checksum: 75a6d645fb122dad29c06a7597bddea977258957ed88d7a6df59b5cd3fe4a527e253e9bbf2e783e4b73657f9098b96a5fe96ab8a113655d4109108577ecf85b0 + languageName: node + linkType: hard + +"minipass-collect@npm:^1.0.2": + version: 1.0.2 + resolution: "minipass-collect@npm:1.0.2" + dependencies: + minipass: ^3.0.0 + checksum: 14df761028f3e47293aee72888f2657695ec66bd7d09cae7ad558da30415fdc4752bbfee66287dcc6fd5e6a2fa3466d6c484dc1cbd986525d9393b9523d97f10 + languageName: node + linkType: hard + +"minipass-fetch@npm:^3.0.0": + version: 3.0.4 + resolution: "minipass-fetch@npm:3.0.4" + dependencies: + encoding: ^0.1.13 + minipass: ^7.0.3 + minipass-sized: ^1.0.3 + minizlib: ^2.1.2 + dependenciesMeta: + encoding: + optional: true + checksum: af7aad15d5c128ab1ebe52e043bdf7d62c3c6f0cecb9285b40d7b395e1375b45dcdfd40e63e93d26a0e8249c9efd5c325c65575aceee192883970ff8cb11364a + languageName: node + linkType: hard + +"minipass-flush@npm:^1.0.5": + version: 1.0.5 + resolution: "minipass-flush@npm:1.0.5" + dependencies: + minipass: ^3.0.0 + checksum: 56269a0b22bad756a08a94b1ffc36b7c9c5de0735a4dd1ab2b06c066d795cfd1f0ac44a0fcae13eece5589b908ecddc867f04c745c7009be0b566421ea0944cf + languageName: node + linkType: hard + +"minipass-pipeline@npm:^1.2.4": + version: 1.2.4 + resolution: "minipass-pipeline@npm:1.2.4" + dependencies: + minipass: ^3.0.0 + checksum: b14240dac0d29823c3d5911c286069e36d0b81173d7bdf07a7e4a91ecdef92cdff4baaf31ea3746f1c61e0957f652e641223970870e2353593f382112257971b + languageName: node + linkType: hard + +"minipass-sized@npm:^1.0.3": + version: 1.0.3 + resolution: "minipass-sized@npm:1.0.3" + dependencies: + minipass: ^3.0.0 + checksum: 79076749fcacf21b5d16dd596d32c3b6bf4d6e62abb43868fac21674078505c8b15eaca4e47ed844985a4514854f917d78f588fcd029693709417d8f98b2bd60 + languageName: node + linkType: hard + +"minipass@npm:^3.0.0": + version: 3.3.6 + resolution: "minipass@npm:3.3.6" + dependencies: + yallist: ^4.0.0 + checksum: a30d083c8054cee83cdcdc97f97e4641a3f58ae743970457b1489ce38ee1167b3aaf7d815cd39ec7a99b9c40397fd4f686e83750e73e652b21cb516f6d845e48 + languageName: node + linkType: hard + +"minipass@npm:^5.0.0": + version: 5.0.0 + resolution: "minipass@npm:5.0.0" + checksum: 425dab288738853fded43da3314a0b5c035844d6f3097a8e3b5b29b328da8f3c1af6fc70618b32c29ff906284cf6406b6841376f21caaadd0793c1d5a6a620ea + languageName: node + linkType: hard + +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.3": + version: 7.0.3 + resolution: "minipass@npm:7.0.3" + checksum: 6f1614f5b5b55568a46bca5fec0e7c46dac027691db27d0e1923a8192866903144cd962ac772c0e9f89b608ea818b702709c042bce98e190d258847d85461531 + languageName: node + linkType: hard + +"minizlib@npm:^2.1.1, minizlib@npm:^2.1.2": + version: 2.1.2 + resolution: "minizlib@npm:2.1.2" + dependencies: + minipass: ^3.0.0 + yallist: ^4.0.0 + checksum: f1fdeac0b07cf8f30fcf12f4b586795b97be856edea22b5e9072707be51fc95d41487faec3f265b42973a304fe3a64acd91a44a3826a963e37b37bafde0212c3 + languageName: node + linkType: hard + +"mkdirp@npm:^1.0.3": + version: 1.0.4 + resolution: "mkdirp@npm:1.0.4" + bin: + mkdirp: bin/cmd.js + checksum: a96865108c6c3b1b8e1d5e9f11843de1e077e57737602de1b82030815f311be11f96f09cce59bd5b903d0b29834733e5313f9301e3ed6d6f6fba2eae0df4298f + languageName: node + linkType: hard + +"ms@npm:2.1.2": + version: 2.1.2 + resolution: "ms@npm:2.1.2" + checksum: 673cdb2c3133eb050c745908d8ce632ed2c02d85640e2edb3ace856a2266a813b30c613569bf3354fdf4ea7d1a1494add3bfa95e2713baa27d0c2c71fc44f58f + languageName: node + linkType: hard + +"ms@npm:^2.0.0": + version: 2.1.3 + resolution: "ms@npm:2.1.3" + checksum: aa92de608021b242401676e35cfa5aa42dd70cbdc082b916da7fb925c542173e36bce97ea3e804923fe92c0ad991434e4a38327e15a1b5b5f945d66df615ae6d + languageName: node + linkType: hard + +"nanoid@npm:^3.3.6": + version: 3.3.6 + resolution: "nanoid@npm:3.3.6" + bin: + nanoid: bin/nanoid.cjs + checksum: 7d0eda657002738aa5206107bd0580aead6c95c460ef1bdd0b1a87a9c7ae6277ac2e9b945306aaa5b32c6dcb7feaf462d0f552e7f8b5718abfc6ead5c94a71b3 + languageName: node + linkType: hard + +"negotiator@npm:^0.6.3": + version: 0.6.3 + resolution: "negotiator@npm:0.6.3" + checksum: b8ffeb1e262eff7968fc90a2b6767b04cfd9842582a9d0ece0af7049537266e7b2506dfb1d107a32f06dd849ab2aea834d5830f7f4d0e5cb7d36e1ae55d021d9 + languageName: node + linkType: hard + +"neo-async@npm:^2.6.0": + version: 2.6.2 + resolution: "neo-async@npm:2.6.2" + checksum: deac9f8d00eda7b2e5cd1b2549e26e10a0faa70adaa6fdadca701cc55f49ee9018e427f424bac0c790b7c7e2d3068db97f3093f1093975f2acb8f8818b936ed9 + languageName: node + linkType: hard + +"node-gyp@npm:latest": + version: 9.4.0 + resolution: "node-gyp@npm:9.4.0" + dependencies: + env-paths: ^2.2.0 + exponential-backoff: ^3.1.1 + glob: ^7.1.4 + graceful-fs: ^4.2.6 + make-fetch-happen: ^11.0.3 + nopt: ^6.0.0 + npmlog: ^6.0.0 + rimraf: ^3.0.2 + semver: ^7.3.5 + tar: ^6.1.2 + which: ^2.0.2 + bin: + node-gyp: bin/node-gyp.js + checksum: 78b404e2e0639d64e145845f7f5a3cb20c0520cdaf6dda2f6e025e9b644077202ea7de1232396ba5bde3fee84cdc79604feebe6ba3ec84d464c85d407bb5da99 + languageName: node + linkType: hard + +"node-releases@npm:^2.0.13": + version: 2.0.13 + resolution: "node-releases@npm:2.0.13" + checksum: 17ec8f315dba62710cae71a8dad3cd0288ba943d2ece43504b3b1aa8625bf138637798ab470b1d9035b0545996f63000a8a926e0f6d35d0996424f8b6d36dda3 + languageName: node + linkType: hard + +"nopt@npm:^6.0.0": + version: 6.0.0 + resolution: "nopt@npm:6.0.0" + dependencies: + abbrev: ^1.0.0 + bin: + nopt: bin/nopt.js + checksum: 82149371f8be0c4b9ec2f863cc6509a7fd0fa729929c009f3a58e4eb0c9e4cae9920e8f1f8eb46e7d032fec8fb01bede7f0f41a67eb3553b7b8e14fa53de1dac + languageName: node + linkType: hard + +"normalize-path@npm:^3.0.0, normalize-path@npm:~3.0.0": + version: 3.0.0 + resolution: "normalize-path@npm:3.0.0" + checksum: 88eeb4da891e10b1318c4b2476b6e2ecbeb5ff97d946815ffea7794c31a89017c70d7f34b3c2ebf23ef4e9fc9fb99f7dffe36da22011b5b5c6ffa34f4873ec20 + languageName: node + linkType: hard + +"normalize-range@npm:^0.1.2": + version: 0.1.2 + resolution: "normalize-range@npm:0.1.2" + checksum: 9b2f14f093593f367a7a0834267c24f3cb3e887a2d9809c77d8a7e5fd08738bcd15af46f0ab01cc3a3d660386f015816b5c922cea8bf2ee79777f40874063184 + languageName: node + linkType: hard + +"npmlog@npm:^6.0.0": + version: 6.0.2 + resolution: "npmlog@npm:6.0.2" + dependencies: + are-we-there-yet: ^3.0.0 + console-control-strings: ^1.1.0 + gauge: ^4.0.3 + set-blocking: ^2.0.0 + checksum: ae238cd264a1c3f22091cdd9e2b106f684297d3c184f1146984ecbe18aaa86343953f26b9520dedd1b1372bc0316905b736c1932d778dbeb1fcf5a1001390e2a + languageName: node + linkType: hard + +"nth-check@npm:^2.0.1": + version: 2.1.1 + resolution: "nth-check@npm:2.1.1" + dependencies: + boolbase: ^1.0.0 + checksum: 5afc3dafcd1573b08877ca8e6148c52abd565f1d06b1eb08caf982e3fa289a82f2cae697ffb55b5021e146d60443f1590a5d6b944844e944714a5b549675bcd3 + languageName: node + linkType: hard + +"nwsapi@npm:^2.2.0": + version: 2.2.7 + resolution: "nwsapi@npm:2.2.7" + checksum: cab25f7983acec7e23490fec3ef7be608041b460504229770e3bfcf9977c41d6fe58f518994d3bd9aa3a101f501089a3d4a63536f4ff8ae4b8c4ca23bdbfda4e + languageName: node + linkType: hard + +"once@npm:^1.3.0": + version: 1.4.0 + resolution: "once@npm:1.4.0" + dependencies: + wrappy: 1 + checksum: cd0a88501333edd640d95f0d2700fbde6bff20b3d4d9bdc521bdd31af0656b5706570d6c6afe532045a20bb8dc0849f8332d6f2a416e0ba6d3d3b98806c7db68 + languageName: node + linkType: hard + +"p-map@npm:^4.0.0": + version: 4.0.0 + resolution: "p-map@npm:4.0.0" + dependencies: + aggregate-error: ^3.0.0 + checksum: cb0ab21ec0f32ddffd31dfc250e3afa61e103ef43d957cc45497afe37513634589316de4eb88abdfd969fe6410c22c0b93ab24328833b8eb1ccc087fc0442a1c + languageName: node + linkType: hard + +"parse5-htmlparser2-tree-adapter@npm:^7.0.0": + version: 7.0.0 + resolution: "parse5-htmlparser2-tree-adapter@npm:7.0.0" + dependencies: + domhandler: ^5.0.2 + parse5: ^7.0.0 + checksum: fc5d01e07733142a1baf81de5c2a9c41426c04b7ab29dd218acb80cd34a63177c90aff4a4aee66cf9f1d0aeecff1389adb7452ad6f8af0a5888e3e9ad6ef733d + languageName: node + linkType: hard + +"parse5@npm:6.0.1": + version: 6.0.1 + resolution: "parse5@npm:6.0.1" + checksum: 7d569a176c5460897f7c8f3377eff640d54132b9be51ae8a8fa4979af940830b2b0c296ce75e5bd8f4041520aadde13170dbdec44889975f906098ea0002f4bd + languageName: node + linkType: hard + +"parse5@npm:^7.0.0": + version: 7.1.2 + resolution: "parse5@npm:7.1.2" + dependencies: + entities: ^4.4.0 + checksum: 59465dd05eb4c5ec87b76173d1c596e152a10e290b7abcda1aecf0f33be49646ea74840c69af975d7887543ea45564801736356c568d6b5e71792fd0f4055713 + languageName: node + linkType: hard + +"path-is-absolute@npm:^1.0.0": + version: 1.0.1 + resolution: "path-is-absolute@npm:1.0.1" + checksum: 060840f92cf8effa293bcc1bea81281bd7d363731d214cbe5c227df207c34cd727430f70c6037b5159c8a870b9157cba65e775446b0ab06fd5ecc7e54615a3b8 + languageName: node + linkType: hard + +"path-key@npm:^3.1.0": + version: 3.1.1 + resolution: "path-key@npm:3.1.1" + checksum: 55cd7a9dd4b343412a8386a743f9c746ef196e57c823d90ca3ab917f90ab9f13dd0ded27252ba49dbdfcab2b091d998bc446f6220cd3cea65db407502a740020 + languageName: node + linkType: hard + +"path-parse@npm:^1.0.7": + version: 1.0.7 + resolution: "path-parse@npm:1.0.7" + checksum: 49abf3d81115642938a8700ec580da6e830dde670be21893c62f4e10bd7dd4c3742ddc603fe24f898cba7eb0c6bc1777f8d9ac14185d34540c6d4d80cd9cae8a + languageName: node + linkType: hard + +"path-scurry@npm:^1.10.1": + version: 1.10.1 + resolution: "path-scurry@npm:1.10.1" + dependencies: + lru-cache: ^9.1.1 || ^10.0.0 + minipass: ^5.0.0 || ^6.0.2 || ^7.0.0 + checksum: e2557cff3a8fb8bc07afdd6ab163a92587884f9969b05bbbaf6fe7379348bfb09af9ed292af12ed32398b15fb443e81692047b786d1eeb6d898a51eb17ed7d90 + languageName: node + linkType: hard + +"path-type@npm:^4.0.0": + version: 4.0.0 + resolution: "path-type@npm:4.0.0" + checksum: 5b1e2daa247062061325b8fdbfd1fb56dde0a448fb1455453276ea18c60685bdad23a445dc148cf87bc216be1573357509b7d4060494a6fd768c7efad833ee45 + languageName: node + linkType: hard + +"picocolors@npm:^1.0.0": + version: 1.0.0 + resolution: "picocolors@npm:1.0.0" + checksum: a2e8092dd86c8396bdba9f2b5481032848525b3dc295ce9b57896f931e63fc16f79805144321f72976383fc249584672a75cc18d6777c6b757603f372f745981 + languageName: node + linkType: hard + +"picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.3.1": + version: 2.3.1 + resolution: "picomatch@npm:2.3.1" + checksum: 050c865ce81119c4822c45d3c84f1ced46f93a0126febae20737bd05ca20589c564d6e9226977df859ed5e03dc73f02584a2b0faad36e896936238238b0446cf + languageName: node + linkType: hard + +"postcss-value-parser@npm:^4.2.0": + version: 4.2.0 + resolution: "postcss-value-parser@npm:4.2.0" + checksum: 819ffab0c9d51cf0acbabf8996dffbfafbafa57afc0e4c98db88b67f2094cb44488758f06e5da95d7036f19556a4a732525e84289a425f4f6fd8e412a9d7442f + languageName: node + linkType: hard + +"postcss@npm:^8.4.31": + version: 8.4.31 + resolution: "postcss@npm:8.4.31" + dependencies: + nanoid: ^3.3.6 + picocolors: ^1.0.0 + source-map-js: ^1.0.2 + checksum: 1d8611341b073143ad90486fcdfeab49edd243377b1f51834dc4f6d028e82ce5190e4f11bb2633276864503654fb7cab28e67abdc0fbf9d1f88cad4a0ff0beea + languageName: node + linkType: hard + +"promise-retry@npm:^2.0.1": + version: 2.0.1 + resolution: "promise-retry@npm:2.0.1" + dependencies: + err-code: ^2.0.2 + retry: ^0.12.0 + checksum: f96a3f6d90b92b568a26f71e966cbbc0f63ab85ea6ff6c81284dc869b41510e6cdef99b6b65f9030f0db422bf7c96652a3fff9f2e8fb4a0f069d8f4430359429 + languageName: node + linkType: hard + +"psl@npm:^1.1.33": + version: 1.9.0 + resolution: "psl@npm:1.9.0" + checksum: 20c4277f640c93d393130673f392618e9a8044c6c7bf61c53917a0fddb4952790f5f362c6c730a9c32b124813e173733f9895add8d26f566ed0ea0654b2e711d + languageName: node + linkType: hard + +"punycode@npm:^2.1.1": + version: 2.3.0 + resolution: "punycode@npm:2.3.0" + checksum: 39f760e09a2a3bbfe8f5287cf733ecdad69d6af2fe6f97ca95f24b8921858b91e9ea3c9eeec6e08cede96181b3bb33f95c6ffd8c77e63986508aa2e8159fa200 + languageName: node + linkType: hard + +"querystringify@npm:^2.1.1": + version: 2.2.0 + resolution: "querystringify@npm:2.2.0" + checksum: 5641ea231bad7ef6d64d9998faca95611ed4b11c2591a8cae741e178a974f6a8e0ebde008475259abe1621cb15e692404e6b6626e927f7b849d5c09392604b15 + languageName: node + linkType: hard + +"queue-microtask@npm:^1.2.2": + version: 1.2.3 + resolution: "queue-microtask@npm:1.2.3" + checksum: b676f8c040cdc5b12723ad2f91414d267605b26419d5c821ff03befa817ddd10e238d22b25d604920340fd73efd8ba795465a0377c4adf45a4a41e4234e42dc4 + languageName: node + linkType: hard + +"readable-stream@npm:^3.6.0": + version: 3.6.2 + resolution: "readable-stream@npm:3.6.2" + dependencies: + inherits: ^2.0.3 + string_decoder: ^1.1.1 + util-deprecate: ^1.0.1 + checksum: bdcbe6c22e846b6af075e32cf8f4751c2576238c5043169a1c221c92ee2878458a816a4ea33f4c67623c0b6827c8a400409bfb3cf0bf3381392d0b1dfb52ac8d + languageName: node + linkType: hard + +"readdirp@npm:~3.6.0": + version: 3.6.0 + resolution: "readdirp@npm:3.6.0" + dependencies: + picomatch: ^2.2.1 + checksum: 1ced032e6e45670b6d7352d71d21ce7edf7b9b928494dcaba6f11fba63180d9da6cd7061ebc34175ffda6ff529f481818c962952004d273178acd70f7059b320 + languageName: node + linkType: hard + +"requires-port@npm:^1.0.0": + version: 1.0.0 + resolution: "requires-port@npm:1.0.0" + checksum: eee0e303adffb69be55d1a214e415cf42b7441ae858c76dfc5353148644f6fd6e698926fc4643f510d5c126d12a705e7c8ed7e38061113bdf37547ab356797ff + languageName: node + linkType: hard + +"resolve@npm:^1.22.6": + version: 1.22.6 + resolution: "resolve@npm:1.22.6" + dependencies: + is-core-module: ^2.13.0 + path-parse: ^1.0.7 + supports-preserve-symlinks-flag: ^1.0.0 + bin: + resolve: bin/resolve + checksum: d13bf66d4e2ee30d291491f16f2fa44edd4e0cefb85d53249dd6f93e70b2b8c20ec62f01b18662e3cd40e50a7528f18c4087a99490048992a3bb954cf3201a5b + languageName: node + linkType: hard + +"resolve@patch:resolve@^1.22.6#~builtin": + version: 1.22.6 + resolution: "resolve@patch:resolve@npm%3A1.22.6#~builtin::version=1.22.6&hash=07638b" + dependencies: + is-core-module: ^2.13.0 + path-parse: ^1.0.7 + supports-preserve-symlinks-flag: ^1.0.0 + bin: + resolve: bin/resolve + checksum: 9d3b3c67aefd12cecbe5f10ca4d1f51ea190891096497c43f301b086883b426466918c3a64f1bbf1788fabb52b579d58809614006c5d0b49186702b3b8fb746a + languageName: node + linkType: hard + +"retry@npm:^0.12.0": + version: 0.12.0 + resolution: "retry@npm:0.12.0" + checksum: 623bd7d2e5119467ba66202d733ec3c2e2e26568074923bc0585b6b99db14f357e79bdedb63cab56cec47491c4a0da7e6021a7465ca6dc4f481d3898fdd3158c + languageName: node + linkType: hard + +"reusify@npm:^1.0.4": + version: 1.0.4 + resolution: "reusify@npm:1.0.4" + checksum: c3076ebcc22a6bc252cb0b9c77561795256c22b757f40c0d8110b1300723f15ec0fc8685e8d4ea6d7666f36c79ccc793b1939c748bf36f18f542744a4e379fcc + languageName: node + linkType: hard + +"rimraf@npm:^3.0.2": + version: 3.0.2 + resolution: "rimraf@npm:3.0.2" + dependencies: + glob: ^7.1.3 + bin: + rimraf: bin.js + checksum: 87f4164e396f0171b0a3386cc1877a817f572148ee13a7e113b238e48e8a9f2f31d009a92ec38a591ff1567d9662c6b67fd8818a2dbbaed74bc26a87a2a4a9a0 + languageName: node + linkType: hard + +"run-parallel@npm:^1.1.9": + version: 1.2.0 + resolution: "run-parallel@npm:1.2.0" + dependencies: + queue-microtask: ^1.2.2 + checksum: cb4f97ad25a75ebc11a8ef4e33bb962f8af8516bb2001082ceabd8902e15b98f4b84b4f8a9b222e5d57fc3bd1379c483886ed4619367a7680dad65316993021d + languageName: node + linkType: hard + +"safe-buffer@npm:~5.2.0": + version: 5.2.1 + resolution: "safe-buffer@npm:5.2.1" + checksum: b99c4b41fdd67a6aaf280fcd05e9ffb0813654894223afb78a31f14a19ad220bba8aba1cb14eddce1fcfb037155fe6de4e861784eb434f7d11ed58d1e70dd491 + languageName: node + linkType: hard + +"safer-buffer@npm:>= 2.1.2 < 3, safer-buffer@npm:>= 2.1.2 < 3.0.0": + version: 2.1.2 + resolution: "safer-buffer@npm:2.1.2" + checksum: cab8f25ae6f1434abee8d80023d7e72b598cf1327164ddab31003c51215526801e40b66c5e65d658a0af1e9d6478cadcb4c745f4bd6751f97d8644786c0978b0 + languageName: node + linkType: hard + +"sass@npm:^1.7.3": + version: 1.69.0 + resolution: "sass@npm:1.69.0" + dependencies: + chokidar: ">=3.0.0 <4.0.0" + immutable: ^4.0.0 + source-map-js: ">=0.6.2 <2.0.0" + bin: + sass: sass.js + checksum: eabea31ea3b1dd529c7eff345c8b6468afe6ab8011bd4f95caa2cffb8fb115cc055ea21de425be6197f7ed22516f5652eccb98d315d592ea152ada553f964b8a + languageName: node + linkType: hard + +"saxes@npm:^5.0.1": + version: 5.0.1 + resolution: "saxes@npm:5.0.1" + dependencies: + xmlchars: ^2.2.0 + checksum: 5636b55cf15f7cf0baa73f2797bf992bdcf75d1b39d82c0aa4608555c774368f6ac321cb641fd5f3d3ceb87805122cd47540da6a7b5960fe0dbdb8f8c263f000 + languageName: node + linkType: hard + +"semver@npm:^7.3.5": + version: 7.5.4 + resolution: "semver@npm:7.5.4" + dependencies: + lru-cache: ^6.0.0 + bin: + semver: bin/semver.js + checksum: 12d8ad952fa353b0995bf180cdac205a4068b759a140e5d3c608317098b3575ac2f1e09182206bf2eb26120e1c0ed8fb92c48c592f6099680de56bb071423ca3 + languageName: node + linkType: hard + +"set-blocking@npm:^2.0.0": + version: 2.0.0 + resolution: "set-blocking@npm:2.0.0" + checksum: 6e65a05f7cf7ebdf8b7c75b101e18c0b7e3dff4940d480efed8aad3a36a4005140b660fa1d804cb8bce911cac290441dc728084a30504d3516ac2ff7ad607b02 + languageName: node + linkType: hard + +"shebang-command@npm:^2.0.0": + version: 2.0.0 + resolution: "shebang-command@npm:2.0.0" + dependencies: + shebang-regex: ^3.0.0 + checksum: 6b52fe87271c12968f6a054e60f6bde5f0f3d2db483a1e5c3e12d657c488a15474121a1d55cd958f6df026a54374ec38a4a963988c213b7570e1d51575cea7fa + languageName: node + linkType: hard + +"shebang-regex@npm:^3.0.0": + version: 3.0.0 + resolution: "shebang-regex@npm:3.0.0" + checksum: 1a2bcae50de99034fcd92ad4212d8e01eedf52c7ec7830eedcf886622804fe36884278f2be8be0ea5fde3fd1c23911643a4e0f726c8685b61871c8908af01222 + languageName: node + linkType: hard + +"signal-exit@npm:^3.0.7": + version: 3.0.7 + resolution: "signal-exit@npm:3.0.7" + checksum: a2f098f247adc367dffc27845853e9959b9e88b01cb301658cfe4194352d8d2bb32e18467c786a7fe15f1d44b233ea35633d076d5e737870b7139949d1ab6318 + languageName: node + linkType: hard + +"signal-exit@npm:^4.0.1": + version: 4.1.0 + resolution: "signal-exit@npm:4.1.0" + checksum: 64c757b498cb8629ffa5f75485340594d2f8189e9b08700e69199069c8e3070fb3e255f7ab873c05dc0b3cec412aea7402e10a5990cb6a050bd33ba062a6c549 + languageName: node + linkType: hard + +"slash@npm:^3.0.0": + version: 3.0.0 + resolution: "slash@npm:3.0.0" + checksum: 94a93fff615f25a999ad4b83c9d5e257a7280c90a32a7cb8b4a87996e4babf322e469c42b7f649fd5796edd8687652f3fb452a86dc97a816f01113183393f11c + languageName: node + linkType: hard + +"smart-buffer@npm:^4.2.0": + version: 4.2.0 + resolution: "smart-buffer@npm:4.2.0" + checksum: b5167a7142c1da704c0e3af85c402002b597081dd9575031a90b4f229ca5678e9a36e8a374f1814c8156a725d17008ae3bde63b92f9cfd132526379e580bec8b + languageName: node + linkType: hard + +"socks-proxy-agent@npm:^7.0.0": + version: 7.0.0 + resolution: "socks-proxy-agent@npm:7.0.0" + dependencies: + agent-base: ^6.0.2 + debug: ^4.3.3 + socks: ^2.6.2 + checksum: 720554370154cbc979e2e9ce6a6ec6ced205d02757d8f5d93fe95adae454fc187a5cbfc6b022afab850a5ce9b4c7d73e0f98e381879cf45f66317a4895953846 + languageName: node + linkType: hard + +"socks@npm:^2.6.2": + version: 2.7.1 + resolution: "socks@npm:2.7.1" + dependencies: + ip: ^2.0.0 + smart-buffer: ^4.2.0 + checksum: 259d9e3e8e1c9809a7f5c32238c3d4d2a36b39b83851d0f573bfde5f21c4b1288417ce1af06af1452569cd1eb0841169afd4998f0e04ba04656f6b7f0e46d748 + languageName: node + linkType: hard + +"source-map-js@npm:>=0.6.2 <2.0.0, source-map-js@npm:^1.0.2": + version: 1.0.2 + resolution: "source-map-js@npm:1.0.2" + checksum: c049a7fc4deb9a7e9b481ae3d424cc793cb4845daa690bc5a05d428bf41bf231ced49b4cf0c9e77f9d42fdb3d20d6187619fc586605f5eabe995a316da8d377c + languageName: node + linkType: hard + +"source-map@npm:^0.6.1, source-map@npm:~0.6.1": + version: 0.6.1 + resolution: "source-map@npm:0.6.1" + checksum: 59ce8640cf3f3124f64ac289012c2b8bd377c238e316fb323ea22fbfe83da07d81e000071d7242cad7a23cd91c7de98e4df8830ec3f133cb6133a5f6e9f67bc2 + languageName: node + linkType: hard + +"ssri@npm:^10.0.0": + version: 10.0.5 + resolution: "ssri@npm:10.0.5" + dependencies: + minipass: ^7.0.3 + checksum: 0a31b65f21872dea1ed3f7c200d7bc1c1b91c15e419deca14f282508ba917cbb342c08a6814c7f68ca4ca4116dd1a85da2bbf39227480e50125a1ceffeecb750 + languageName: node + linkType: hard + +"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^1.0.2 || 2 || 3 || 4, string-width@npm:^4.1.0, string-width@npm:^4.2.3": + version: 4.2.3 + resolution: "string-width@npm:4.2.3" + dependencies: + emoji-regex: ^8.0.0 + is-fullwidth-code-point: ^3.0.0 + strip-ansi: ^6.0.1 + checksum: e52c10dc3fbfcd6c3a15f159f54a90024241d0f149cf8aed2982a2d801d2e64df0bf1dc351cf8e95c3319323f9f220c16e740b06faecd53e2462df1d2b5443fb + languageName: node + linkType: hard + +"string-width@npm:^5.0.1, string-width@npm:^5.1.2": + version: 5.1.2 + resolution: "string-width@npm:5.1.2" + dependencies: + eastasianwidth: ^0.2.0 + emoji-regex: ^9.2.2 + strip-ansi: ^7.0.1 + checksum: 7369deaa29f21dda9a438686154b62c2c5f661f8dda60449088f9f980196f7908fc39fdd1803e3e01541970287cf5deae336798337e9319a7055af89dafa7193 + languageName: node + linkType: hard + +"string_decoder@npm:^1.1.1": + version: 1.3.0 + resolution: "string_decoder@npm:1.3.0" + dependencies: + safe-buffer: ~5.2.0 + checksum: 8417646695a66e73aefc4420eb3b84cc9ffd89572861fe004e6aeb13c7bc00e2f616247505d2dbbef24247c372f70268f594af7126f43548565c68c117bdeb56 + languageName: node + linkType: hard + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": + version: 6.0.1 + resolution: "strip-ansi@npm:6.0.1" + dependencies: + ansi-regex: ^5.0.1 + checksum: f3cd25890aef3ba6e1a74e20896c21a46f482e93df4a06567cebf2b57edabb15133f1f94e57434e0a958d61186087b1008e89c94875d019910a213181a14fc8c + languageName: node + linkType: hard + +"strip-ansi@npm:^7.0.1": + version: 7.1.0 + resolution: "strip-ansi@npm:7.1.0" + dependencies: + ansi-regex: ^6.0.1 + checksum: 859c73fcf27869c22a4e4d8c6acfe690064659e84bef9458aa6d13719d09ca88dcfd40cbf31fd0be63518ea1a643fe070b4827d353e09533a5b0b9fd4553d64d + languageName: node + linkType: hard + +"supports-color@npm:^7.1.0": + version: 7.2.0 + resolution: "supports-color@npm:7.2.0" + dependencies: + has-flag: ^4.0.0 + checksum: 3dda818de06ebbe5b9653e07842d9479f3555ebc77e9a0280caf5a14fb877ffee9ed57007c3b78f5a6324b8dbeec648d9e97a24e2ed9fdb81ddc69ea07100f4a + languageName: node + linkType: hard + +"supports-preserve-symlinks-flag@npm:^1.0.0": + version: 1.0.0 + resolution: "supports-preserve-symlinks-flag@npm:1.0.0" + checksum: 53b1e247e68e05db7b3808b99b892bd36fb096e6fba213a06da7fab22045e97597db425c724f2bbd6c99a3c295e1e73f3e4de78592289f38431049e1277ca0ae + languageName: node + linkType: hard + +"symbol-tree@npm:^3.2.4": + version: 3.2.4 + resolution: "symbol-tree@npm:3.2.4" + checksum: 6e8fc7e1486b8b54bea91199d9535bb72f10842e40c79e882fc94fb7b14b89866adf2fd79efa5ebb5b658bc07fb459ccce5ac0e99ef3d72f474e74aaf284029d + languageName: node + linkType: hard + +"tar@npm:^6.1.11, tar@npm:^6.1.2": + version: 6.1.15 + resolution: "tar@npm:6.1.15" + dependencies: + chownr: ^2.0.0 + fs-minipass: ^2.0.0 + minipass: ^5.0.0 + minizlib: ^2.1.1 + mkdirp: ^1.0.3 + yallist: ^4.0.0 + checksum: f23832fceeba7578bf31907aac744ae21e74a66f4a17a9e94507acf460e48f6db598c7023882db33bab75b80e027c21f276d405e4a0322d58f51c7088d428268 + languageName: node + linkType: hard + +"to-regex-range@npm:^5.0.1": + version: 5.0.1 + resolution: "to-regex-range@npm:5.0.1" + dependencies: + is-number: ^7.0.0 + checksum: f76fa01b3d5be85db6a2a143e24df9f60dd047d151062d0ba3df62953f2f697b16fe5dad9b0ac6191c7efc7b1d9dcaa4b768174b7b29da89d4428e64bc0a20ed + languageName: node + linkType: hard + +"tough-cookie@npm:^4.0.0": + version: 4.1.3 + resolution: "tough-cookie@npm:4.1.3" + dependencies: + psl: ^1.1.33 + punycode: ^2.1.1 + universalify: ^0.2.0 + url-parse: ^1.5.3 + checksum: c9226afff36492a52118432611af083d1d8493a53ff41ec4ea48e5b583aec744b989e4280bcf476c910ec1525a89a4a0f1cae81c08b18fb2ec3a9b3a72b91dcc + languageName: node + linkType: hard + +"tr46@npm:^2.1.0": + version: 2.1.0 + resolution: "tr46@npm:2.1.0" + dependencies: + punycode: ^2.1.1 + checksum: ffe6049b9dca3ae329b059aada7f515b0f0064c611b39b51ff6b53897e954650f6f63d9319c6c008d36ead477c7b55e5f64c9dc60588ddc91ff720d64eb710b3 + languageName: node + linkType: hard + +"tr46@npm:^3.0.0": + version: 3.0.0 + resolution: "tr46@npm:3.0.0" + dependencies: + punycode: ^2.1.1 + checksum: 44c3cc6767fb800490e6e9fd64fd49041aa4e49e1f6a012b34a75de739cc9ed3a6405296072c1df8b6389ae139c5e7c6496f659cfe13a04a4bff3a1422981270 + languageName: node + linkType: hard + +"tslib@npm:^2.4.0": + version: 2.6.0 + resolution: "tslib@npm:2.6.0" + checksum: c01066038f950016a18106ddeca4649b4d76caa76ec5a31e2a26e10586a59fceb4ee45e96719bf6c715648e7c14085a81fee5c62f7e9ebee68e77a5396e5538f + languageName: node + linkType: hard + +"typescript@npm:^5.1.6": + version: 5.2.2 + resolution: "typescript@npm:5.2.2" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 7912821dac4d962d315c36800fe387cdc0a6298dba7ec171b350b4a6e988b51d7b8f051317786db1094bd7431d526b648aba7da8236607febb26cf5b871d2d3c + languageName: node + linkType: hard + +"typescript@patch:typescript@^5.1.6#~builtin": + version: 5.2.2 + resolution: "typescript@patch:typescript@npm%3A5.2.2#~builtin::version=5.2.2&hash=7ad353" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 07106822b4305de3f22835cbba949a2b35451cad50888759b6818421290ff95d522b38ef7919e70fb381c5fe9c1c643d7dea22c8b31652a717ddbd57b7f4d554 + languageName: node + linkType: hard + +"uglify-js@npm:^3.1.4": + version: 3.17.4 + resolution: "uglify-js@npm:3.17.4" + bin: + uglifyjs: bin/uglifyjs + checksum: 7b3897df38b6fc7d7d9f4dcd658599d81aa2b1fb0d074829dd4e5290f7318dbca1f4af2f45acb833b95b1fe0ed4698662ab61b87e94328eb4c0a0d3435baf924 + languageName: node + linkType: hard + +"unique-filename@npm:^3.0.0": + version: 3.0.0 + resolution: "unique-filename@npm:3.0.0" + dependencies: + unique-slug: ^4.0.0 + checksum: 8e2f59b356cb2e54aab14ff98a51ac6c45781d15ceaab6d4f1c2228b780193dc70fae4463ce9e1df4479cb9d3304d7c2043a3fb905bdeca71cc7e8ce27e063df + languageName: node + linkType: hard + +"unique-slug@npm:^4.0.0": + version: 4.0.0 + resolution: "unique-slug@npm:4.0.0" + dependencies: + imurmurhash: ^0.1.4 + checksum: 0884b58365af59f89739e6f71e3feacb5b1b41f2df2d842d0757933620e6de08eff347d27e9d499b43c40476cbaf7988638d3acb2ffbcb9d35fd035591adfd15 + languageName: node + linkType: hard + +"universalify@npm:^0.2.0": + version: 0.2.0 + resolution: "universalify@npm:0.2.0" + checksum: e86134cb12919d177c2353196a4cc09981524ee87abf621f7bc8d249dbbbebaec5e7d1314b96061497981350df786e4c5128dbf442eba104d6e765bc260678b5 + languageName: node + linkType: hard + +"update-browserslist-db@npm:^1.0.13": + version: 1.0.13 + resolution: "update-browserslist-db@npm:1.0.13" + dependencies: + escalade: ^3.1.1 + picocolors: ^1.0.0 + peerDependencies: + browserslist: ">= 4.21.0" + bin: + update-browserslist-db: cli.js + checksum: 1e47d80182ab6e4ad35396ad8b61008ae2a1330221175d0abd37689658bdb61af9b705bfc41057fd16682474d79944fb2d86767c5ed5ae34b6276b9bed353322 + languageName: node + linkType: hard + +"url-parse@npm:^1.5.3": + version: 1.5.10 + resolution: "url-parse@npm:1.5.10" + dependencies: + querystringify: ^2.1.1 + requires-port: ^1.0.0 + checksum: fbdba6b1d83336aca2216bbdc38ba658d9cfb8fc7f665eb8b17852de638ff7d1a162c198a8e4ed66001ddbf6c9888d41e4798912c62b4fd777a31657989f7bdf + languageName: node + linkType: hard + +"util-deprecate@npm:^1.0.1": + version: 1.0.2 + resolution: "util-deprecate@npm:1.0.2" + checksum: 474acf1146cb2701fe3b074892217553dfcf9a031280919ba1b8d651a068c9b15d863b7303cb15bd00a862b498e6cf4ad7b4a08fb134edd5a6f7641681cb54a2 + languageName: node + linkType: hard + +"w3c-hr-time@npm:^1.0.2": + version: 1.0.2 + resolution: "w3c-hr-time@npm:1.0.2" + dependencies: + browser-process-hrtime: ^1.0.0 + checksum: ec3c2dacbf8050d917bbf89537a101a08c2e333b4c19155f7d3bedde43529d4339db6b3d049d9610789cb915f9515f8be037e0c54c079e9d4735c50b37ed52b9 + languageName: node + linkType: hard + +"w3c-xmlserializer@npm:^2.0.0": + version: 2.0.0 + resolution: "w3c-xmlserializer@npm:2.0.0" + dependencies: + xml-name-validator: ^3.0.0 + checksum: ae25c51cf71f1fb2516df1ab33a481f83461a117565b95e3d0927432522323f93b1b2846cbb60196d337970c421adb604fc2d0d180c6a47a839da01db5b9973b + languageName: node + linkType: hard + +"webidl-conversions@npm:^5.0.0": + version: 5.0.0 + resolution: "webidl-conversions@npm:5.0.0" + checksum: ccf1ec2ca7c0b5671e5440ace4a66806ae09c49016ab821481bec0c05b1b82695082dc0a27d1fe9d804d475a408ba0c691e6803fd21be608e710955d4589cd69 + languageName: node + linkType: hard + +"webidl-conversions@npm:^6.1.0": + version: 6.1.0 + resolution: "webidl-conversions@npm:6.1.0" + checksum: 1f526507aa491f972a0c1409d07f8444e1d28778dfa269a9971f2e157182f3d496dc33296e4ed45b157fdb3bf535bb90c90bf10c50dcf1dd6caacb2a34cc84fb + languageName: node + linkType: hard + +"webidl-conversions@npm:^7.0.0": + version: 7.0.0 + resolution: "webidl-conversions@npm:7.0.0" + checksum: f05588567a2a76428515333eff87200fae6c83c3948a7482ebb109562971e77ef6dc49749afa58abb993391227c5697b3ecca52018793e0cb4620a48f10bd21b + languageName: node + linkType: hard + +"whatwg-encoding@npm:^1.0.5": + version: 1.0.5 + resolution: "whatwg-encoding@npm:1.0.5" + dependencies: + iconv-lite: 0.4.24 + checksum: 5be4efe111dce29ddee3448d3915477fcc3b28f991d9cf1300b4e50d6d189010d47bca2f51140a844cf9b726e8f066f4aee72a04d687bfe4f2ee2767b2f5b1e6 + languageName: node + linkType: hard + +"whatwg-mimetype@npm:^2.3.0": + version: 2.3.0 + resolution: "whatwg-mimetype@npm:2.3.0" + checksum: 23eb885940bcbcca4ff841c40a78e9cbb893ec42743993a42bf7aed16085b048b44b06f3402018931687153550f9a32d259dfa524e4f03577ab898b6965e5383 + languageName: node + linkType: hard + +"whatwg-mimetype@npm:^3.0.0": + version: 3.0.0 + resolution: "whatwg-mimetype@npm:3.0.0" + checksum: ce08bbb36b6aaf64f3a84da89707e3e6a31e5ab1c1a2379fd68df79ba712a4ab090904f0b50e6693b0dafc8e6343a6157e40bf18fdffd26e513cf95ee2a59824 + languageName: node + linkType: hard + +"whatwg-url@npm:^11.0.0": + version: 11.0.0 + resolution: "whatwg-url@npm:11.0.0" + dependencies: + tr46: ^3.0.0 + webidl-conversions: ^7.0.0 + checksum: ed4826aaa57e66bb3488a4b25c9cd476c46ba96052747388b5801f137dd740b73fde91ad207d96baf9f17fbcc80fc1a477ad65181b5eb5fa718d27c69501d7af + languageName: node + linkType: hard + +"whatwg-url@npm:^9.0.0": + version: 9.1.0 + resolution: "whatwg-url@npm:9.1.0" + dependencies: + tr46: ^2.1.0 + webidl-conversions: ^6.1.0 + checksum: cfee81bb7f87036e1151da15cefd3076fa97a4a4a658c4b58f6e74891acf25f180aa955e761cda77995f6e260b8dc3c4326ebc83d539ed978a50062c6b3bd0d1 + languageName: node + linkType: hard + +"which@npm:^2.0.1, which@npm:^2.0.2": + version: 2.0.2 + resolution: "which@npm:2.0.2" + dependencies: + isexe: ^2.0.0 + bin: + node-which: ./bin/node-which + checksum: 1a5c563d3c1b52d5f893c8b61afe11abc3bab4afac492e8da5bde69d550de701cf9806235f20a47b5c8fa8a1d6a9135841de2596535e998027a54589000e66d1 + languageName: node + linkType: hard + +"wide-align@npm:^1.1.5": + version: 1.1.5 + resolution: "wide-align@npm:1.1.5" + dependencies: + string-width: ^1.0.2 || 2 || 3 || 4 + checksum: d5fc37cd561f9daee3c80e03b92ed3e84d80dde3365a8767263d03dacfc8fa06b065ffe1df00d8c2a09f731482fcacae745abfbb478d4af36d0a891fad4834d3 + languageName: node + linkType: hard + +"wordwrap@npm:^1.0.0": + version: 1.0.0 + resolution: "wordwrap@npm:1.0.0" + checksum: 2a44b2788165d0a3de71fd517d4880a8e20ea3a82c080ce46e294f0b68b69a2e49cff5f99c600e275c698a90d12c5ea32aff06c311f0db2eb3f1201f3e7b2a04 + languageName: node + linkType: hard + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version: 7.0.0 + resolution: "wrap-ansi@npm:7.0.0" + dependencies: + ansi-styles: ^4.0.0 + string-width: ^4.1.0 + strip-ansi: ^6.0.0 + checksum: a790b846fd4505de962ba728a21aaeda189b8ee1c7568ca5e817d85930e06ef8d1689d49dbf0e881e8ef84436af3a88bc49115c2e2788d841ff1b8b5b51a608b + languageName: node + linkType: hard + +"wrap-ansi@npm:^8.1.0": + version: 8.1.0 + resolution: "wrap-ansi@npm:8.1.0" + dependencies: + ansi-styles: ^6.1.0 + string-width: ^5.0.1 + strip-ansi: ^7.0.1 + checksum: 371733296dc2d616900ce15a0049dca0ef67597d6394c57347ba334393599e800bab03c41d4d45221b6bc967b8c453ec3ae4749eff3894202d16800fdfe0e238 + languageName: node + linkType: hard + +"wrappy@npm:1": + version: 1.0.2 + resolution: "wrappy@npm:1.0.2" + checksum: 159da4805f7e84a3d003d8841557196034155008f817172d4e986bd591f74aa82aa7db55929a54222309e01079a65a92a9e6414da5a6aa4b01ee44a511ac3ee5 + languageName: node + linkType: hard + +"ws@npm:^8.0.0": + version: 8.13.0 + resolution: "ws@npm:8.13.0" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 53e991bbf928faf5dc6efac9b8eb9ab6497c69feeb94f963d648b7a3530a720b19ec2e0ec037344257e05a4f35bd9ad04d9de6f289615ffb133282031b18c61c + languageName: node + linkType: hard + +"xml-name-validator@npm:^3.0.0": + version: 3.0.0 + resolution: "xml-name-validator@npm:3.0.0" + checksum: b3ac459afed783c285bb98e4960bd1f3ba12754fd4f2320efa0f9181ca28928c53cc75ca660d15d205e81f92304419afe94c531c7cfb3e0649aa6d140d53ecb0 + languageName: node + linkType: hard + +"xmlchars@npm:^2.2.0": + version: 2.2.0 + resolution: "xmlchars@npm:2.2.0" + checksum: 8c70ac94070ccca03f47a81fcce3b271bd1f37a591bf5424e787ae313fcb9c212f5f6786e1fa82076a2c632c0141552babcd85698c437506dfa6ae2d58723062 + languageName: node + linkType: hard + +"yallist@npm:^4.0.0": + version: 4.0.0 + resolution: "yallist@npm:4.0.0" + checksum: 343617202af32df2a15a3be36a5a8c0c8545208f3d3dfbc6bb7c3e3b7e8c6f8e7485432e4f3b88da3031a6e20afa7c711eded32ddfb122896ac5d914e75848d5 + languageName: node + linkType: hard diff --git a/scripts/extra_script.py b/scripts/extra_script.py index 18fe2c0..8ca464f 100644 --- a/scripts/extra_script.py +++ b/scripts/extra_script.py @@ -4,4 +4,4 @@ Import("env") def before_buildfs(source, target, env): env.Execute("cd data && yarn && yarn build") -env.AddPreAction("$BUILD_DIR/spiffs.bin", before_buildfs) +env.AddPreAction("$BUILD_DIR/littlefs.bin", before_buildfs) diff --git a/src/lib/block_notify.cpp b/src/lib/block_notify.cpp index c11e6d5..6378a50 100644 --- a/src/lib/block_notify.cpp +++ b/src/lib/block_notify.cpp @@ -1,8 +1,7 @@ #include "block_notify.hpp" -const char *wsServer = "wss://mempool.space/api/v1/ws"; -// WebsocketsClient client; -esp_websocket_client_handle_t client; +char *wsServer; +esp_websocket_client_handle_t blockNotifyClient = NULL; unsigned long int currentBlockHeight; void setupBlockNotify() @@ -36,15 +35,17 @@ void setupBlockNotify() xTaskNotifyGive(blockUpdateTaskHandle); } + // std::strcpy(wsServer, String("wss://" + mempoolInstance + "/api/v1/ws").c_str()); + esp_websocket_client_config_t config = { .uri = "wss://mempool.bitcoin.nl/api/v1/ws", }; Serial.printf("Connecting to %s\r\n", config.uri); - client = esp_websocket_client_init(&config); - esp_websocket_register_events(client, WEBSOCKET_EVENT_ANY, onWebsocketEvent, client); - esp_websocket_client_start(client); + blockNotifyClient = esp_websocket_client_init(&config); + esp_websocket_register_events(blockNotifyClient, WEBSOCKET_EVENT_ANY, onWebsocketEvent, blockNotifyClient); + esp_websocket_client_start(blockNotifyClient); } void onWebsocketEvent(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) @@ -58,7 +59,7 @@ void onWebsocketEvent(void *handler_args, esp_event_base_t base, int32_t event_i Serial.println("Connected to Mempool.space WebSocket"); sub = "{\"action\": \"want\", \"data\":[\"blocks\"]}"; - if (esp_websocket_client_send_text(client, sub.c_str(), sub.length(), portMAX_DELAY) == -1) + if (esp_websocket_client_send_text(blockNotifyClient, sub.c_str(), sub.length(), portMAX_DELAY) == -1) { Serial.println("Mempool.space WS Block Subscribe Error"); } @@ -92,8 +93,10 @@ void onWebsocketMessage(esp_websocket_event_data_t *event_data) Serial.print("New block found: "); Serial.println(block["height"].as()); - if (blockUpdateTaskHandle != nullptr) + if (blockUpdateTaskHandle != nullptr) { xTaskNotifyGive(blockUpdateTaskHandle); + queueLedEffect(LED_FLASH_BLOCK_NOTIFY); + } } doc.clear(); @@ -102,4 +105,10 @@ void onWebsocketMessage(esp_websocket_event_data_t *event_data) unsigned long getBlockHeight() { return currentBlockHeight; +} + +bool isBlockNotifyConnected() { + if (blockNotifyClient == NULL) + return false; + return esp_websocket_client_is_connected(blockNotifyClient); } \ No newline at end of file diff --git a/src/lib/block_notify.hpp b/src/lib/block_notify.hpp index b0a70aa..ebbcfc7 100644 --- a/src/lib/block_notify.hpp +++ b/src/lib/block_notify.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -8,6 +9,7 @@ #include "esp_websocket_client.h" #include "screen_handler.hpp" +#include "led_handler.hpp" //using namespace websockets; @@ -16,4 +18,5 @@ void setupBlockNotify(); void onWebsocketEvent(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data); void onWebsocketMessage(esp_websocket_event_data_t* event_data); -unsigned long getBlockHeight(); \ No newline at end of file +unsigned long getBlockHeight(); +bool isBlockNotifyConnected(); diff --git a/src/lib/button_handler.cpp b/src/lib/button_handler.cpp index 4d287ce..12a0ef4 100644 --- a/src/lib/button_handler.cpp +++ b/src/lib/button_handler.cpp @@ -18,22 +18,21 @@ void buttonTask(void *parameter) { uint pin = mcp.getLastInterruptPin(); - Serial.printf("Button pressed: %d", pin); - // switch (pin) - // { - // case 3: - // toggleScreenTimer(); - // break; - // case 2: - // nextScreen(); - // break; - // case 1: - // previousScreen(); - // break; - // case 0: - // showNetworkSettings(); - // break; - // } + switch (pin) + { + case 3: + toggleTimerActive(); + break; + case 2: + nextScreen(); + break; + case 1: + previousScreen(); + break; + case 0: + showSystemStatusScreen(); + break; + } } mcp.clearInterrupts(); // Very ugly, but for some reason this is necessary diff --git a/src/lib/button_handler.hpp b/src/lib/button_handler.hpp index 02849c2..fa503fb 100644 --- a/src/lib/button_handler.hpp +++ b/src/lib/button_handler.hpp @@ -4,6 +4,7 @@ #include #include #include "shared.hpp" +#include "screen_handler.hpp" extern TaskHandle_t buttonTaskHandle; diff --git a/src/lib/config.cpp b/src/lib/config.cpp index 9579316..125c9ab 100644 --- a/src/lib/config.cpp +++ b/src/lib/config.cpp @@ -1,27 +1,22 @@ #include "config.hpp" -#ifndef NEOPIXEL_PIN -#define NEOPIXEL_PIN 34 -#endif -#ifndef NEOPIXEL_COUNT -#define NEOPIXEL_COUNT 4 -#endif + #define MAX_ATTEMPTS_WIFI_CONNECTION 20 Preferences preferences; Adafruit_MCP23X17 mcp; -Adafruit_NeoPixel pixels(NEOPIXEL_COUNT, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800); +std::map screenNameMap; void setup() { setupHardware(); - if (mcp.digitalRead(3) == LOW) { + if (mcp.digitalRead(3) == LOW) + { WiFi.eraseAP(); blinkDelay(100, 3); } - setupDisplays(); tryImprovSetup(); @@ -47,9 +42,9 @@ void tryImprovSetup() // blinkDelay(100, 3); // } // else - // { - // WiFi.begin(); - // } + { + WiFi.begin(); + } uint8_t x_buffer[16]; uint8_t x_position = 0; @@ -69,7 +64,8 @@ void tryImprovSetup() x_position = 0; } } - // vTaskDelay(1); + + vTaskDelay(1 / portTICK_PERIOD_MS); } } @@ -91,6 +87,15 @@ void setupTime() void setupPreferences() { preferences.begin("btclock", false); + + setFgColor(preferences.getUInt("fgColor", DEFAULT_FG_COLOR)); + setBgColor(preferences.getUInt("bgColor", DEFAULT_BG_COLOR)); + + screenNameMap = {{SCREEN_BLOCK_HEIGHT, "Block Height"}, + {SCREEN_MSCW_TIME, "Sats per dollar"}, + {SCREEN_BTC_TICKER, "Ticker"}, + {SCREEN_TIME, "Time"}, + {SCREEN_HALVING_COUNTDOWN, "Halving countdown"}}; } void setupWebsocketClients() @@ -107,18 +112,16 @@ void setupTimers() void finishSetup() { - pixels.clear(); - pixels.show(); + clearLeds(); +} + +std::map getScreenNameMap() { + return screenNameMap; } void setupHardware() { - pixels.begin(); - pixels.setPixelColor(0, pixels.Color(255, 0, 0)); - pixels.setPixelColor(1, pixels.Color(0, 255, 0)); - pixels.setPixelColor(2, pixels.Color(0, 0, 255)); - pixels.setPixelColor(3, pixels.Color(255, 255, 255)); - pixels.show(); + setupLeds(); if (psramInit()) { @@ -129,7 +132,6 @@ void setupHardware() Serial.println(F("PSRAM not available")); } - Wire.begin(35, 36, 400000); if (!mcp.begin_I2C(0x20)) @@ -153,7 +155,6 @@ void setupHardware() { mcp.pinMode(i, OUTPUT); } - } } @@ -194,41 +195,20 @@ bool improv_connectWifi(std::string ssid, std::string password) return true; } -void blinkDelay(int d, int times) -{ - for (int j = 0; j < times; j++) - { - - pixels.setPixelColor(0, pixels.Color(255, 0, 0)); - pixels.setPixelColor(1, pixels.Color(0, 255, 0)); - pixels.setPixelColor(2, pixels.Color(255, 0, 0)); - pixels.setPixelColor(3, pixels.Color(0, 255, 0)); - pixels.show(); - vTaskDelay(pdMS_TO_TICKS(d)); - - pixels.setPixelColor(0, pixels.Color(255, 255, 0)); - pixels.setPixelColor(1, pixels.Color(0, 255, 255)); - pixels.setPixelColor(2, pixels.Color(255, 255, 0)); - pixels.setPixelColor(3, pixels.Color(0, 255, 255)); - pixels.show(); - vTaskDelay(pdMS_TO_TICKS(d)); - } - pixels.clear(); - pixels.show(); -} void onImprovErrorCallback(improv::Error err) { - pixels.setPixelColor(0, pixels.Color(255, 0, 0)); - pixels.setPixelColor(1, pixels.Color(255, 0, 0)); - pixels.setPixelColor(2, pixels.Color(255, 0, 0)); - pixels.setPixelColor(3, pixels.Color(255, 0, 0)); - pixels.show(); - vTaskDelay(pdMS_TO_TICKS(100)); + blinkDelayColor(100, 1, 255,0,0); + // pixels.setPixelColor(0, pixels.Color(255, 0, 0)); + // pixels.setPixelColor(1, pixels.Color(255, 0, 0)); + // pixels.setPixelColor(2, pixels.Color(255, 0, 0)); + // pixels.setPixelColor(3, pixels.Color(255, 0, 0)); + // pixels.show(); + // vTaskDelay(pdMS_TO_TICKS(100)); - pixels.clear(); - pixels.show(); - vTaskDelay(pdMS_TO_TICKS(100)); + // pixels.clear(); + // pixels.show(); + // vTaskDelay(pdMS_TO_TICKS(100)); } std::vector getLocalUrl() @@ -272,7 +252,7 @@ bool onImprovCommandCallback(improv::ImprovCommand cmd) if (improv_connectWifi(cmd.ssid, cmd.password)) { - + blinkDelay(100, 3); // std::array epdContent = {"S", "U", "C", "C", "E", "S", "S"}; // setEpdContent(epdContent); diff --git a/src/lib/config.hpp b/src/lib/config.hpp index 72204f7..65b2c17 100644 --- a/src/lib/config.hpp +++ b/src/lib/config.hpp @@ -2,7 +2,6 @@ #include #include #include -#include #include "shared.hpp" #include @@ -16,6 +15,7 @@ #include "lib/block_notify.hpp" #include "lib/price_notify.hpp" #include "lib/button_handler.hpp" +#include "lib/led_handler.hpp" #define NTP_SERVER "pool.ntp.org" #define DEFAULT_MEMPOOL_INSTANCE "mempool.space" @@ -23,6 +23,9 @@ #define USER_AGENT "BTClock/2.0" #define MCP_DEV_ADDR 0x20 +#define DEFAULT_FG_COLOR GxEPD_WHITE +#define DEFAULT_BG_COLOR GxEPD_BLACK + #define BITCOIND_HOST "" #define BITCOIND_PORT 8332 #define BITCOIND_RPC_USER "" @@ -36,6 +39,7 @@ void setupHardware(); void tryImprovSetup(); void setupTimers(); void finishSetup(); +std::map getScreenNameMap(); std::vector getLocalUrl(); bool improv_connectWifi(std::string ssid, std::string password); @@ -45,4 +49,3 @@ void onImprovErrorCallback(improv::Error err); void improv_set_state(improv::State state); void improv_send_response(std::vector &response); void improv_set_error(improv::Error error); -void blinkDelay(int d, int times); \ No newline at end of file diff --git a/src/lib/epd.cpp b/src/lib/epd.cpp index 96486a0..162799e 100644 --- a/src/lib/epd.cpp +++ b/src/lib/epd.cpp @@ -76,7 +76,7 @@ void setupDisplays() int *taskParam = new int; *taskParam = i; - xTaskCreate(updateDisplay, "EpdUpd" + char(i), 4096, taskParam, 1, &tasks[i]); // create task + xTaskCreate(updateDisplay, "EpdUpd" + char(i), 4096, taskParam, tskIDLE_PRIORITY, &tasks[i]); // create task } epdContent = {"B", @@ -91,7 +91,7 @@ void setupDisplays() xTaskNotifyGive(tasks[i]); } - xTaskCreate(taskEpd, "epd_task", 2048, NULL, 1, NULL); + xTaskCreate(taskEpd, "epd_task", 2048, NULL, tskIDLE_PRIORITY, NULL); } void taskEpd(void *pvParameters) diff --git a/src/lib/led_handler.cpp b/src/lib/led_handler.cpp index 77fd7aa..cb4303e 100644 --- a/src/lib/led_handler.cpp +++ b/src/lib/led_handler.cpp @@ -1,18 +1,216 @@ #include "led_handler.hpp" TaskHandle_t ledTaskHandle = NULL; +QueueHandle_t ledTaskQueue = NULL; +Adafruit_NeoPixel pixels(NEOPIXEL_COUNT, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800); + const TickType_t debounceDelay = pdMS_TO_TICKS(50); +uint32_t notificationValue; +unsigned long ledTaskParams; void ledTask(void *parameter) { while (1) { - ulTaskNotifyTake(pdTRUE, portMAX_DELAY); - + if (ledTaskQueue != NULL) + { + if (xQueueReceive(ledTaskQueue, &ledTaskParams, portMAX_DELAY) == pdPASS) + { + uint32_t oldLights[NEOPIXEL_COUNT]; + + // get current state + for (int i = 0; i < NEOPIXEL_COUNT; i++) + { + oldLights[i] = pixels.getPixelColor(i); + } + + switch (ledTaskParams) + { + case LED_FLASH_ERROR: + blinkDelayColor(250, 3, 255, 0, 0); + break; + case LED_FLASH_SUCCESS: + blinkDelayColor(250, 3, 0, 255, 0); + break; + case LED_FLASH_UPDATE: + break; + case LED_FLASH_BLOCK_NOTIFY: + blinkDelayTwoColor(250, 3, pixels.Color(224, 67, 0), pixels.Color(8, 2, 0)); + break; + case LED_EFFECT_PAUSE_TIMER: + for (int i = NEOPIXEL_COUNT; i >= 0; i--) + { + for (int j = NEOPIXEL_COUNT; j >= 0; j--) + { + uint32_t c = pixels.Color(0, 0, 0); + if (i == j) + c = pixels.Color(0, 255, 0); + pixels.setPixelColor(j, c); + } + + pixels.show(); + + delay(100); + } + + delay(900); + + pixels.clear(); + pixels.show(); + break; + case LED_EFFECT_START_TIMER: + pixels.clear(); + pixels.setPixelColor(NEOPIXEL_COUNT, pixels.Color(0, 255, 0)); + pixels.show(); + + delay(900); + + for (int i = NEOPIXEL_COUNT; i--; i > 0) + { + + for (int j = NEOPIXEL_COUNT; j--; j > 0) + { + uint32_t c = pixels.Color(0, 0, 0); + if (i == j) + c = pixels.Color(0, 255, 0); + + pixels.setPixelColor(j, c); + } + + pixels.show(); + + delay(100); + } + + pixels.clear(); + pixels.show(); + break; + } + + // revert to previous state + for (int i = 0; i < NEOPIXEL_COUNT; i++) + { + pixels.setPixelColor(i, oldLights[i]); + } + + pixels.show(); + } + } } } +void setupLeds() +{ + pixels.begin(); + pixels.setBrightness(preferences.getUInt("ledBrightness", 128)); + pixels.setPixelColor(0, pixels.Color(255, 0, 0)); + pixels.setPixelColor(1, pixels.Color(0, 255, 0)); + pixels.setPixelColor(2, pixels.Color(0, 0, 255)); + pixels.setPixelColor(3, pixels.Color(255, 255, 255)); + pixels.show(); + setupLedTask(); +} + void setupLedTask() { - xTaskCreate(ledTask, "LedTask", 4096, NULL, tskIDLE_PRIORITY, &ledTaskHandle); // Create the FreeRTOS task + ledTaskQueue = xQueueCreate(10, sizeof(unsigned long)); + + xTaskCreate(ledTask, "LedTask", 4096, NULL, tskIDLE_PRIORITY, &ledTaskHandle); } + +void blinkDelay(int d, int times) +{ + for (int j = 0; j < times; j++) + { + + pixels.setPixelColor(0, pixels.Color(255, 0, 0)); + pixels.setPixelColor(1, pixels.Color(0, 255, 0)); + pixels.setPixelColor(2, pixels.Color(255, 0, 0)); + pixels.setPixelColor(3, pixels.Color(0, 255, 0)); + pixels.show(); + vTaskDelay(pdMS_TO_TICKS(d)); + + pixels.setPixelColor(0, pixels.Color(255, 255, 0)); + pixels.setPixelColor(1, pixels.Color(0, 255, 255)); + pixels.setPixelColor(2, pixels.Color(255, 255, 0)); + pixels.setPixelColor(3, pixels.Color(0, 255, 255)); + pixels.show(); + vTaskDelay(pdMS_TO_TICKS(d)); + } + pixels.clear(); + pixels.show(); +} + +void blinkDelayColor(int d, int times, uint r, uint g, uint b) +{ + for (int j = 0; j < times; j++) + { + for (int i = 0; i < NEOPIXEL_COUNT; i++) + { + pixels.setPixelColor(i, pixels.Color(r, g, b)); + } + + pixels.show(); + vTaskDelay(pdMS_TO_TICKS(d)); + + pixels.clear(); + pixels.show(); + vTaskDelay(pdMS_TO_TICKS(d)); + } + pixels.clear(); + pixels.show(); +} + +void blinkDelayTwoColor(int d, int times, uint32_t c1, uint32_t c2) +{ + for (int j = 0; j < times; j++) + { + for (int i = 0; i < NEOPIXEL_COUNT; i++) + { + pixels.setPixelColor(i, c1); + } + pixels.show(); + vTaskDelay(pdMS_TO_TICKS(d)); + + for (int i = 0; i < NEOPIXEL_COUNT; i++) + { + pixels.setPixelColor(i, c2); + } + pixels.show(); + vTaskDelay(pdMS_TO_TICKS(d)); + } + pixels.clear(); + pixels.show(); +} + +void clearLeds() +{ + pixels.clear(); + pixels.show(); +} + +void setLights(int r, int g, int b) +{ + for (int i = 0; i < NEOPIXEL_COUNT; i++) + { + pixels.setPixelColor(i, pixels.Color(r, g, b)); + } + + pixels.show(); +} + +QueueHandle_t getLedTaskQueue() +{ + return ledTaskQueue; +} + +bool queueLedEffect(uint effect) +{ + if (ledTaskQueue == NULL) + { + return false; + } + + unsigned long flashType = effect; + xQueueSend(ledTaskQueue, &flashType, portMAX_DELAY); +} \ No newline at end of file diff --git a/src/lib/led_handler.hpp b/src/lib/led_handler.hpp index b7d41c7..2e57d63 100644 --- a/src/lib/led_handler.hpp +++ b/src/lib/led_handler.hpp @@ -6,7 +6,33 @@ #include #include "shared.hpp" +#ifndef NEOPIXEL_PIN +#define NEOPIXEL_PIN 34 +#endif +#ifndef NEOPIXEL_COUNT +#define NEOPIXEL_COUNT 4 +#endif + +typedef struct { + int flashType; +} LedTaskParameters; + +const int LED_FLASH_ERROR = 0; +const int LED_FLASH_SUCCESS = 1; +const int LED_FLASH_UPDATE = 2; +const int LED_FLASH_BLOCK_NOTIFY = 3; +const int LED_EFFECT_START_TIMER = 4; +const int LED_EFFECT_PAUSE_TIMER = 5; + extern TaskHandle_t ledTaskHandle; void ledTask(void *pvParameters); +void setupLeds(); void setupLedTask(); +void blinkDelay(int d, int times); +void blinkDelayColor(int d, int times, uint r, uint g, uint b); +void blinkDelayTwoColor(int d, int times, uint32_t c1, uint32_t c2); +void clearLeds(); +QueueHandle_t getLedTaskQueue(); +bool queueLedEffect(uint effect); +void setLights(int r, int g, int b); \ No newline at end of file diff --git a/src/lib/price_notify.cpp b/src/lib/price_notify.cpp index 73a83be..40c906c 100644 --- a/src/lib/price_notify.cpp +++ b/src/lib/price_notify.cpp @@ -2,7 +2,7 @@ const char *wsServerPrice = "wss://ws.coincap.io/prices?assets=bitcoin"; // WebsocketsClient client; -esp_websocket_client_handle_t clientPrice; +esp_websocket_client_handle_t clientPrice = NULL; unsigned long int currentPrice; void setupPriceNotify() @@ -46,7 +46,6 @@ void onWebsocketPriceMessage(esp_websocket_event_data_t* event_data) if (doc.containsKey("bitcoin")) { if (currentPrice != doc["bitcoin"].as()) { - // Serial.printf("New price %lu\r\n", currentPrice); const unsigned long oldPrice = currentPrice; currentPrice = doc["bitcoin"].as(); @@ -61,4 +60,10 @@ void onWebsocketPriceMessage(esp_websocket_event_data_t* event_data) unsigned long getPrice() { return currentPrice; +} + +bool isPriceNotifyConnected() { + if (clientPrice == NULL) + return false; + return esp_websocket_client_is_connected(clientPrice); } \ No newline at end of file diff --git a/src/lib/price_notify.hpp b/src/lib/price_notify.hpp index a375319..e6f7ad2 100644 --- a/src/lib/price_notify.hpp +++ b/src/lib/price_notify.hpp @@ -14,4 +14,5 @@ void setupPriceNotify(); void onWebsocketPriceEvent(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data); void onWebsocketPriceMessage(esp_websocket_event_data_t* event_data); -unsigned long getPrice(); \ No newline at end of file +unsigned long getPrice(); +bool isPriceNotifyConnected(); \ No newline at end of file diff --git a/src/lib/screen_handler.cpp b/src/lib/screen_handler.cpp index d545e20..bec727c 100644 --- a/src/lib/screen_handler.cpp +++ b/src/lib/screen_handler.cpp @@ -61,7 +61,16 @@ void taskScreenRotate(void *pvParameters) { ulTaskNotifyTake(pdTRUE, portMAX_DELAY); - setCurrentScreen((currentScreen+1) % 5); + int nextScreen = (currentScreen+ 1) % 5; + String key = "screen" + String(nextScreen) + "Visible"; + + while (!preferences.getBool(key.c_str(), true)) + { + nextScreen = (nextScreen + 1) % 5; + key = "screen" + String(nextScreen) + "Visible"; + } + + setCurrentScreen(nextScreen); } } @@ -143,20 +152,6 @@ void taskTimeUpdate(void *pvParameters) } } -const char* int64_to_iso8601(int64_t timestamp) { - time_t seconds = timestamp / 1000000; // Convert microseconds to seconds - struct tm timeinfo; - gmtime_r(&seconds, &timeinfo); - - // Define a buffer to store the formatted time string - static char iso8601[21]; // ISO 8601 time string has the format "YYYY-MM-DDTHH:MM:SSZ" - - // Format the time into the buffer - strftime(iso8601, sizeof(iso8601), "%Y-%m-%dT%H:%M:%SZ", &timeinfo); - - return iso8601; -} - void IRAM_ATTR minuteTimerISR(void *arg) { BaseType_t xHigherPriorityTaskWoken = pdFALSE; @@ -217,11 +212,8 @@ void setupScreenRotateTimer(void *pvParameters) .name = "screen_rotate_timer"}; esp_timer_create(&screenRotateTimerConfig, &screenRotateTimer); - esp_timer_start_periodic(screenRotateTimer, getTimerSeconds() * usPerSecond); - Serial.println("Set up Screen Rotate Timer"); - vTaskDelete(NULL); } @@ -240,13 +232,19 @@ void setTimerActive(bool status) if (status) { esp_timer_start_periodic(screenRotateTimer, getTimerSeconds() * usPerSecond); + queueLedEffect(LED_EFFECT_START_TIMER); } else { esp_timer_stop(screenRotateTimer); + queueLedEffect(LED_EFFECT_PAUSE_TIMER); } } +void toggleTimerActive() { + setTimerActive(!isTimerActive()); +} + uint getCurrentScreen() { return currentScreen; @@ -275,4 +273,56 @@ void setCurrentScreen(uint newScreen) xTaskNotifyGive(priceUpdateTaskHandle); break; } +} + +void nextScreen() +{ + int newCurrentScreen = (getCurrentScreen() + 1) % SCREEN_COUNT; + String key = "screen" + String(newCurrentScreen) + "Visible"; + + while (!preferences.getBool(key.c_str(), true)) + { + newCurrentScreen = (newCurrentScreen + 1) % SCREEN_COUNT; + key = "screen" + String(newCurrentScreen) + "Visible"; + } + setCurrentScreen(newCurrentScreen); +} + +void previousScreen() +{ + int newCurrentScreen = modulo(getCurrentScreen() - 1, SCREEN_COUNT); + String key = "screen" + String(newCurrentScreen) + "Visible"; + + while (!preferences.getBool(key.c_str(), true)) + { + newCurrentScreen = modulo(newCurrentScreen - 1, SCREEN_COUNT); + key = "screen" + String(newCurrentScreen) + "Visible"; + } + setCurrentScreen(newCurrentScreen); +} + +void showSystemStatusScreen() +{ + std::array sysStatusEpdContent = {"", "", "", "", "", "", ""}; + + String ipAddr = WiFi.localIP().toString(); + String subNet = WiFi.subnetMask().toString(); + + sysStatusEpdContent[0] = "IP/Subnet"; + + int ipAddrPos = 0; + int subnetPos = 0; + for (int i = 0; i < 4; i++) + { + sysStatusEpdContent[1 + i] = ipAddr.substring(0, ipAddr.indexOf('.')) + "/" + subNet.substring(0, subNet.indexOf('.')); + ipAddrPos = ipAddr.indexOf('.') + 1; + subnetPos = subNet.indexOf('.') + 1; + ipAddr = ipAddr.substring(ipAddrPos); + subNet = subNet.substring(subnetPos); + } + sysStatusEpdContent[NUM_SCREENS-2] = "RAM/Status"; + + sysStatusEpdContent[NUM_SCREENS-1] = String((int)round(ESP.getFreeHeap()/1024)) + "/" + (int)round(ESP.getHeapSize()/1024); + setCurrentScreen(SCREEN_CUSTOM); + setEpdContent(sysStatusEpdContent); } \ No newline at end of file diff --git a/src/lib/screen_handler.hpp b/src/lib/screen_handler.hpp index a7c1d14..37b69a5 100644 --- a/src/lib/screen_handler.hpp +++ b/src/lib/screen_handler.hpp @@ -16,6 +16,10 @@ extern TaskHandle_t taskScreenRotateTaskHandle; uint getCurrentScreen(); void setCurrentScreen(uint newScreen); +void nextScreen(); +void previousScreen(); + +void showSystemStatusScreen(); void setupTimeUpdateTimer(void *pvParameters); void setupScreenRotateTimer(void *pvParameters); @@ -31,7 +35,6 @@ void taskScreenRotate(void *pvParameters); uint getTimerSeconds(); bool isTimerActive(); void setTimerActive(bool status); - +void toggleTimerActive(); void setupTasks(); -const char* int64_to_iso8601(int64_t timestamp); \ No newline at end of file diff --git a/src/lib/shared.hpp b/src/lib/shared.hpp index 697f390..bcd44dc 100644 --- a/src/lib/shared.hpp +++ b/src/lib/shared.hpp @@ -3,6 +3,7 @@ #include #include #include +#include "utils.hpp" extern Adafruit_MCP23X17 mcp; extern Preferences preferences; @@ -15,6 +16,7 @@ const PROGMEM int SCREEN_HALVING_COUNTDOWN = 4; const PROGMEM int SCREEN_COUNTDOWN = 98; const PROGMEM int SCREEN_CUSTOM = 99; const PROGMEM int screens[5] = { SCREEN_BLOCK_HEIGHT, SCREEN_MSCW_TIME, SCREEN_BTC_TICKER, SCREEN_TIME, SCREEN_HALVING_COUNTDOWN }; +const int SCREEN_COUNT = 5; struct SpiRamAllocator { void* allocate(size_t size) { diff --git a/src/lib/utils.cpp b/src/lib/utils.cpp new file mode 100644 index 0000000..8e548f6 --- /dev/null +++ b/src/lib/utils.cpp @@ -0,0 +1,6 @@ +#include "utils.hpp" + +int modulo(int x, int N) +{ + return (x % N + N) % N; +} diff --git a/src/lib/utils.hpp b/src/lib/utils.hpp new file mode 100644 index 0000000..9dad3aa --- /dev/null +++ b/src/lib/utils.hpp @@ -0,0 +1 @@ +int modulo(int x,int N); \ No newline at end of file diff --git a/src/lib/webserver.cpp b/src/lib/webserver.cpp index cd90697..f32fefc 100644 --- a/src/lib/webserver.cpp +++ b/src/lib/webserver.cpp @@ -28,6 +28,10 @@ void setupWebserver() server.on("/api/show/screen", HTTP_GET, onApiShowScreen); server.on("/api/show/text", HTTP_GET, onApiShowText); + server.on("/api/lights/off", HTTP_GET, onApiLightsOff); + server.on("/api/lights/color", HTTP_GET, onApiLightsSetColor); + server.on("^\\/api\\/lights\\/([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$", HTTP_GET, onApiLightsSetColor); + server.on("/api/restart", HTTP_GET, onApiRestart); server.addRewrite(new OneParamRewrite("/api/show/screen/{s}", "/api/show/screen?s={s}")); @@ -59,6 +63,10 @@ void onApiStatus(AsyncWebServerRequest *request) root["espFreePsram"] = ESP.getFreePsram(); root["espPsramSize"] = ESP.getPsramSize(); + JsonObject conStatus = root.createNestedObject("connectionStatus"); + conStatus["price"] = isPriceNotifyConnected(); + conStatus["blocks"] = isBlockNotifyConnected(); + JsonArray data = root.createNestedArray("data"); JsonArray rendered = root.createNestedArray("rendered"); String epdContent[NUM_SCREENS]; @@ -170,14 +178,16 @@ void onApiSettingsGet(AsyncWebServerRequest *request) #endif JsonArray screens = root.createNestedArray("screens"); - // for (int i = 0; i < screenNameMap.size(); i++) - // { - // JsonObject o = screens.createNestedObject(); - // String key = "screen" + String(i) + "Visible"; - // o["id"] = i; - // o["name"] = screenNameMap[i]; - // o["enabled"] = preferences.getBool(key.c_str(), true); - // } + std::map screenNameMap = getScreenNameMap(); + + for (int i = 0; i < screenNameMap.size(); i++) + { + JsonObject o = screens.createNestedObject(); + String key = "screen" + String(i) + "Visible"; + o["id"] = i; + o["name"] = screenNameMap[i]; + o["enabled"] = preferences.getBool(key.c_str(), true); + } AsyncResponseStream *response = request->beginResponseStream("application/json"); serializeJson(root, *response); @@ -274,21 +284,23 @@ void onApiSettingsPost(AsyncWebServerRequest *request) settingsChanged = true; } - // for (int i = 0; i < screenNameMap.size(); i++) - // { - // String key = "screen[" + String(i) + "]"; - // String prefKey = "screen" + String(i) + "Visible"; - // bool visible = false; - // if (request->hasParam(key, true)) - // { - // AsyncWebParameter *screenParam = request->getParam(key, true); - // visible = screenParam->value().toInt(); - // } - // Serial.print("Setting screen " + String(i) + " to "); - // Serial.println(visible); + std::map screenNameMap = getScreenNameMap(); - // preferences.putBool(prefKey.c_str(), visible); - // } + for (int i = 0; i < screenNameMap.size(); i++) + { + String key = "screen[" + String(i) + "]"; + String prefKey = "screen" + String(i) + "Visible"; + bool visible = false; + if (request->hasParam(key, true)) + { + AsyncWebParameter *screenParam = request->getParam(key, true); + visible = screenParam->value().toInt(); + } + Serial.print("Setting screen " + String(i) + " to "); + Serial.println(visible); + + preferences.putBool(prefKey.c_str(), visible); + } if (request->hasParam("tzOffset", true)) { @@ -339,7 +351,7 @@ void onApiSettingsPost(AsyncWebServerRequest *request) request->send(200); if (settingsChanged) { - //flashTemporaryLights(0, 255, 0); + queueLedEffect(LED_FLASH_SUCCESS); Serial.println(F("Settings changed")); } @@ -361,6 +373,22 @@ void onApiSystemStatus(AsyncWebServerRequest *request) request->send(response); } +void onApiLightsOff(AsyncWebServerRequest *request) +{ + setLights(0, 0, 0); + request->send(200); +} + +void onApiLightsSetColor(AsyncWebServerRequest *request) +{ + String rgbColor = request->pathArg(0); + uint r, g, b; + sscanf(rgbColor.c_str(), "%02x%02x%02x", &r, &g, &b); + setLights(r, g, b); + request->send(200, "text/plain", rgbColor); +} + + void onIndex(AsyncWebServerRequest *request) { request->send(LittleFS, "/index.html", String(), false); } void onNotFound(AsyncWebServerRequest *request) diff --git a/src/lib/webserver.hpp b/src/lib/webserver.hpp index 5de2e94..61ee040 100644 --- a/src/lib/webserver.hpp +++ b/src/lib/webserver.hpp @@ -7,7 +7,7 @@ #include "lib/block_notify.hpp" #include "lib/price_notify.hpp" #include "lib/screen_handler.hpp" - +#include "lib/led_handler.hpp" #include "webserver/OneParamRewrite.hpp" @@ -25,6 +25,10 @@ void onApiActionTimerRestart(AsyncWebServerRequest *request); void onApiSettingsGet(AsyncWebServerRequest *request); void onApiSettingsPost(AsyncWebServerRequest *request); +void onApiLightsOff(AsyncWebServerRequest *request); +void onApiLightsSetColor(AsyncWebServerRequest *request); + + void onApiRestart(AsyncWebServerRequest *request); void onIndex(AsyncWebServerRequest *request);