From 7de3b6a5215f452ff9f2723ecaac7cef14ecc38f Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Mon, 12 Feb 2024 15:50:33 -0500 Subject: [PATCH] Migrate to Material Web 1 (#474) * No port pick * Use own components again * Migrate circular progress * Migrate Icon Button * Move button labels to text nodes * Use ew-list for dashboard * Missed one interactive * Migrate select * Migrate textfield * Migrate checkbox/formfield * Remove unused ewt-button * Migrate text field * Divider + dashboard icons * Migrate dialog * Remove mwc components * Clean up icons * Remove old comment * Update connect button * Align top level dialog icon * Avoid scrolling when dialog active * Allow variable for border radius * Cleanup * Bump dependencies * Bump esptool.js to 0.4.1 * Add new device types * Update readme with new device types * Tweak launch button look --- index.html | 29 +- package-lock.json | 2051 ++++++++++++++++--- package.json | 29 +- rollup.config.mjs | 7 +- src/components/ew-checkbox.ts | 14 + src/components/ew-circular-progress.ts | 14 + src/components/ew-dialog.ts | 14 + src/components/ew-divider.ts | 14 + src/components/ew-filled-select.ts | 15 + src/components/ew-filled-text-field.ts | 17 + src/components/ew-icon-button.ts | 15 + src/components/ew-list-item.ts | 14 + src/components/ew-list.ts | 14 + src/components/ew-select-option.ts | 14 + src/components/ew-text-button.ts | 15 + src/components/ewt-button.ts | 25 - src/components/ewt-checkbox.ts | 14 - src/components/ewt-circular-progress.ts | 14 - src/components/ewt-formfield.ts | 14 - src/components/ewt-icon-button.ts | 14 - src/components/ewt-list-item.ts | 14 - src/components/ewt-select.ts | 23 - src/components/ewt-textfield.ts | 23 - src/components/svg.ts | 55 +- src/const.ts | 10 +- src/flash.ts | 9 +- src/install-button.ts | 17 +- src/install-dialog.ts | 807 ++++---- src/no-port-picked/no-port-picked-dialog.ts | 215 +- src/pages/ewt-page-message.ts | 4 - src/pages/ewt-page-progress.ts | 11 +- src/styles.ts | 39 +- 32 files changed, 2616 insertions(+), 968 deletions(-) create mode 100644 src/components/ew-checkbox.ts create mode 100644 src/components/ew-circular-progress.ts create mode 100644 src/components/ew-dialog.ts create mode 100644 src/components/ew-divider.ts create mode 100644 src/components/ew-filled-select.ts create mode 100644 src/components/ew-filled-text-field.ts create mode 100644 src/components/ew-icon-button.ts create mode 100644 src/components/ew-list-item.ts create mode 100644 src/components/ew-list.ts create mode 100644 src/components/ew-select-option.ts create mode 100644 src/components/ew-text-button.ts delete mode 100644 src/components/ewt-button.ts delete mode 100644 src/components/ewt-checkbox.ts delete mode 100644 src/components/ewt-circular-progress.ts delete mode 100644 src/components/ewt-formfield.ts delete mode 100644 src/components/ewt-icon-button.ts delete mode 100644 src/components/ewt-list-item.ts delete mode 100644 src/components/ewt-select.ts delete mode 100644 src/components/ewt-textfield.ts diff --git a/index.html b/index.html index 48292561..151aecf5 100644 --- a/index.html +++ b/index.html @@ -1,4 +1,4 @@ - + @@ -79,8 +79,10 @@ } .screenshot img { max-width: 100%; - box-shadow: rgb(0 0 0 / 20%) 0px 2px 1px -1px, - rgb(0 0 0 / 14%) 0px 1px 1px 0px, rgb(0 0 0 / 12%) 0px 1px 3px 0px; + box-shadow: + rgb(0 0 0 / 20%) 0px 2px 1px -1px, + rgb(0 0 0 / 14%) 0px 1px 1px 0px, + rgb(0 0 0 / 12%) 0px 1px 3px 0px; border-radius: 4px; } .screenshot i { @@ -172,7 +174,7 @@

Try a live demo

device to your computer and hit the button:

The demo is not available because your browser does not support Web @@ -266,9 +268,16 @@

Products using ESP Web Tools

Luciferin
- +
OpenEpaperLink
@@ -366,7 +375,7 @@

Adding ESP Web Tools to your website

 <esp-web-install-button
-  manifest="https://firmware.esphome.io/esphome-web/manifest.json"
+  manifest="https://firmware.esphome.io/esp-web-tools/manifest.json"
 ></esp-web-install-button>

@@ -432,7 +441,8 @@

Creating your manifest

Manifests describe the firmware that you want to offer the user to install. It allows specifying different builds for the different types of ESP devices. Current supported chip families are - ESP8266, ESP32, ESP32-C3, + ESP8266, ESP32, ESP32-C2, + ESP32-C3, ESP32-C6, ESP32-H2, ESP32-S2 and ESP32-S3. The correct build will be automatically selected based on the type of the connected ESP device.

@@ -526,6 +536,7 @@

Customizing the look and feel

  • --esp-tools-button-color
  • --esp-tools-button-text-color
  • +
  • --esp-tools-button-border-radius

There are also some attributes that can be used for styling:

@@ -549,7 +560,7 @@

Replace the button and message with a custom one

 <esp-web-install-button
-  manifest="https://firmware.esphome.io/esphome-web/manifest.json"
+  manifest="https://firmware.esphome.io/esp-web-tools/manifest.json"
 >
   <button slot="activate">Custom install button</button>
   <span slot="unsupported">Ah snap, your browser doesn't work!</span>
diff --git a/package-lock.json b/package-lock.json
index a75c6b6e..6adc74cd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,31 +9,26 @@
       "version": "9.4.3",
       "license": "Apache-2.0",
       "dependencies": {
-        "@material/mwc-button": "^0.27.0",
-        "@material/mwc-checkbox": "^0.27.0",
-        "@material/mwc-circular-progress": "^0.27.0",
-        "@material/mwc-dialog": "^0.27.0",
-        "@material/mwc-formfield": "^0.27.0",
-        "@material/mwc-icon-button": "^0.27.0",
-        "@material/mwc-textfield": "^0.27.0",
-        "esptool-js": "^0.3.2",
+        "@material/web": "^1.2.0",
+        "esptool-js": "^0.4.1",
         "improv-wifi-serial-sdk": "^2.5.0",
-        "lit": "^2.8.0",
+        "lit": "^3.1.2",
         "pako": "^2.1.0",
-        "tslib": "^2.5.3"
+        "tslib": "^2.6.2"
       },
       "devDependencies": {
         "@babel/plugin-proposal-class-properties": "^7.18.6",
         "@rollup/plugin-babel": "^6.0.4",
-        "@rollup/plugin-json": "^6.0.1",
+        "@rollup/plugin-commonjs": "^25.0.7",
+        "@rollup/plugin-json": "^6.1.0",
         "@rollup/plugin-node-resolve": "^15.2.3",
         "@rollup/plugin-terser": "^0.4.4",
-        "@rollup/plugin-typescript": "^11.1.5",
-        "@types/w3c-web-serial": "^1.0.3",
-        "prettier": "^3.0.0",
-        "rollup": "^4.3.0",
-        "serve": "^14.2.0",
-        "typescript": "^5.1.3"
+        "@rollup/plugin-typescript": "^11.1.6",
+        "@types/w3c-web-serial": "^1.0.6",
+        "prettier": "^3.2.5",
+        "rollup": "^4.10.0",
+        "serve": "^14.2.1",
+        "typescript": "^5.3.3"
       }
     },
     "node_modules/@ampproject/remapping": {
@@ -563,9 +558,9 @@
       }
     },
     "node_modules/@jridgewell/sourcemap-codec": {
-      "version": "1.4.14",
-      "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
-      "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
+      "version": "1.4.15",
+      "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
+      "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
       "dev": true
     },
     "node_modules/@jridgewell/trace-mapping": {
@@ -579,16 +574,16 @@
       }
     },
     "node_modules/@lit-labs/ssr-dom-shim": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.1.1.tgz",
-      "integrity": "sha512-kXOeFbfCm4fFf2A3WwVEeQj55tMZa8c8/f9AKHMobQMkzNUfUj+antR3fRPaZJawsa1aZiP/Da3ndpZrwEe4rQ=="
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.2.0.tgz",
+      "integrity": "sha512-yWJKmpGE6lUURKAaIltoPIE/wrbY3TEkqQt+X0m+7fQNnAv0keydnYvbiJFP1PnMhizmIWRWOG5KLhYyc/xl+g=="
     },
     "node_modules/@lit/reactive-element": {
-      "version": "1.6.2",
-      "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.2.tgz",
-      "integrity": "sha512-rDfl+QnCYjuIGf5xI2sVJWdYIi56CTCwWa+nidKYX6oIuBYwUbT/vX4qbUDlHiZKJ/3FRNQ/tWJui44p6/stSA==",
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.0.4.tgz",
+      "integrity": "sha512-GFn91inaUa2oHLak8awSIigYz0cU0Payr1rcFsrkf5OJ5eSPxElyZfKh0f2p9FsTiZWXQdWGJeXZICEfXXYSXQ==",
       "dependencies": {
-        "@lit-labs/ssr-dom-shim": "^1.0.0"
+        "@lit-labs/ssr-dom-shim": "^1.2.0"
       }
     },
     "node_modules/@material/animation": {
@@ -715,19 +710,6 @@
         "@material/rtl": "14.0.0-canary.53b3cad2f.0"
       }
     },
-    "node_modules/@material/form-field": {
-      "version": "14.0.0-canary.53b3cad2f.0",
-      "license": "MIT",
-      "dependencies": {
-        "@material/base": "14.0.0-canary.53b3cad2f.0",
-        "@material/feature-targeting": "14.0.0-canary.53b3cad2f.0",
-        "@material/ripple": "14.0.0-canary.53b3cad2f.0",
-        "@material/rtl": "14.0.0-canary.53b3cad2f.0",
-        "@material/theme": "14.0.0-canary.53b3cad2f.0",
-        "@material/typography": "14.0.0-canary.53b3cad2f.0",
-        "tslib": "^2.1.0"
-      }
-    },
     "node_modules/@material/icon-button": {
       "version": "14.0.0-canary.53b3cad2f.0",
       "license": "MIT",
@@ -816,6 +798,42 @@
         "tslib": "^2.0.1"
       }
     },
+    "node_modules/@material/mwc-base/node_modules/@lit/reactive-element": {
+      "version": "1.6.3",
+      "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+      "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.0.0"
+      }
+    },
+    "node_modules/@material/mwc-base/node_modules/lit": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+      "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+      "dependencies": {
+        "@lit/reactive-element": "^1.6.0",
+        "lit-element": "^3.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/@material/mwc-base/node_modules/lit-element": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+      "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.1.0",
+        "@lit/reactive-element": "^1.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/@material/mwc-base/node_modules/lit-html": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+      "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+      "dependencies": {
+        "@types/trusted-types": "^2.0.2"
+      }
+    },
     "node_modules/@material/mwc-button": {
       "version": "0.27.0",
       "resolved": "https://registry.npmjs.org/@material/mwc-button/-/mwc-button-0.27.0.tgz",
@@ -827,6 +845,42 @@
         "tslib": "^2.0.1"
       }
     },
+    "node_modules/@material/mwc-button/node_modules/@lit/reactive-element": {
+      "version": "1.6.3",
+      "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+      "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.0.0"
+      }
+    },
+    "node_modules/@material/mwc-button/node_modules/lit": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+      "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+      "dependencies": {
+        "@lit/reactive-element": "^1.6.0",
+        "lit-element": "^3.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/@material/mwc-button/node_modules/lit-element": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+      "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.1.0",
+        "@lit/reactive-element": "^1.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/@material/mwc-button/node_modules/lit-html": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+      "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+      "dependencies": {
+        "@types/trusted-types": "^2.0.2"
+      }
+    },
     "node_modules/@material/mwc-checkbox": {
       "version": "0.27.0",
       "resolved": "https://registry.npmjs.org/@material/mwc-checkbox/-/mwc-checkbox-0.27.0.tgz",
@@ -838,6 +892,42 @@
         "tslib": "^2.0.1"
       }
     },
+    "node_modules/@material/mwc-checkbox/node_modules/@lit/reactive-element": {
+      "version": "1.6.3",
+      "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+      "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.0.0"
+      }
+    },
+    "node_modules/@material/mwc-checkbox/node_modules/lit": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+      "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+      "dependencies": {
+        "@lit/reactive-element": "^1.6.0",
+        "lit-element": "^3.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/@material/mwc-checkbox/node_modules/lit-element": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+      "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.1.0",
+        "@lit/reactive-element": "^1.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/@material/mwc-checkbox/node_modules/lit-html": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+      "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+      "dependencies": {
+        "@types/trusted-types": "^2.0.2"
+      }
+    },
     "node_modules/@material/mwc-circular-progress": {
       "version": "0.27.0",
       "resolved": "https://registry.npmjs.org/@material/mwc-circular-progress/-/mwc-circular-progress-0.27.0.tgz",
@@ -850,6 +940,42 @@
         "tslib": "^2.0.1"
       }
     },
+    "node_modules/@material/mwc-circular-progress/node_modules/@lit/reactive-element": {
+      "version": "1.6.3",
+      "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+      "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.0.0"
+      }
+    },
+    "node_modules/@material/mwc-circular-progress/node_modules/lit": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+      "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+      "dependencies": {
+        "@lit/reactive-element": "^1.6.0",
+        "lit-element": "^3.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/@material/mwc-circular-progress/node_modules/lit-element": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+      "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.1.0",
+        "@lit/reactive-element": "^1.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/@material/mwc-circular-progress/node_modules/lit-html": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+      "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+      "dependencies": {
+        "@types/trusted-types": "^2.0.2"
+      }
+    },
     "node_modules/@material/mwc-dialog": {
       "version": "0.27.0",
       "resolved": "https://registry.npmjs.org/@material/mwc-dialog/-/mwc-dialog-0.27.0.tgz",
@@ -865,6 +991,42 @@
         "wicg-inert": "^3.0.0"
       }
     },
+    "node_modules/@material/mwc-dialog/node_modules/@lit/reactive-element": {
+      "version": "1.6.3",
+      "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+      "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.0.0"
+      }
+    },
+    "node_modules/@material/mwc-dialog/node_modules/lit": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+      "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+      "dependencies": {
+        "@lit/reactive-element": "^1.6.0",
+        "lit-element": "^3.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/@material/mwc-dialog/node_modules/lit-element": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+      "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.1.0",
+        "@lit/reactive-element": "^1.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/@material/mwc-dialog/node_modules/lit-html": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+      "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+      "dependencies": {
+        "@types/trusted-types": "^2.0.2"
+      }
+    },
     "node_modules/@material/mwc-floating-label": {
       "version": "0.27.0",
       "resolved": "https://registry.npmjs.org/@material/mwc-floating-label/-/mwc-floating-label-0.27.0.tgz",
@@ -875,15 +1037,40 @@
         "tslib": "^2.0.1"
       }
     },
-    "node_modules/@material/mwc-formfield": {
-      "version": "0.27.0",
-      "resolved": "https://registry.npmjs.org/@material/mwc-formfield/-/mwc-formfield-0.27.0.tgz",
-      "integrity": "sha512-XGZtC1MTyGQ8b2osnaygGzS3qe2QvlWfXZepcFs9i6MW+b6VimQQ4c/KsKIF7dHmeY6N0o4k9pAZ086EGesXOQ==",
+    "node_modules/@material/mwc-floating-label/node_modules/@lit/reactive-element": {
+      "version": "1.6.3",
+      "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+      "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
       "dependencies": {
-        "@material/form-field": "=14.0.0-canary.53b3cad2f.0",
-        "@material/mwc-base": "^0.27.0",
-        "lit": "^2.0.0",
-        "tslib": "^2.0.1"
+        "@lit-labs/ssr-dom-shim": "^1.0.0"
+      }
+    },
+    "node_modules/@material/mwc-floating-label/node_modules/lit": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+      "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+      "dependencies": {
+        "@lit/reactive-element": "^1.6.0",
+        "lit-element": "^3.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/@material/mwc-floating-label/node_modules/lit-element": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+      "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.1.0",
+        "@lit/reactive-element": "^1.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/@material/mwc-floating-label/node_modules/lit-html": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+      "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+      "dependencies": {
+        "@types/trusted-types": "^2.0.2"
       }
     },
     "node_modules/@material/mwc-icon": {
@@ -905,6 +1092,78 @@
         "tslib": "^2.0.1"
       }
     },
+    "node_modules/@material/mwc-icon-button/node_modules/@lit/reactive-element": {
+      "version": "1.6.3",
+      "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+      "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.0.0"
+      }
+    },
+    "node_modules/@material/mwc-icon-button/node_modules/lit": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+      "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+      "dependencies": {
+        "@lit/reactive-element": "^1.6.0",
+        "lit-element": "^3.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/@material/mwc-icon-button/node_modules/lit-element": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+      "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.1.0",
+        "@lit/reactive-element": "^1.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/@material/mwc-icon-button/node_modules/lit-html": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+      "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+      "dependencies": {
+        "@types/trusted-types": "^2.0.2"
+      }
+    },
+    "node_modules/@material/mwc-icon/node_modules/@lit/reactive-element": {
+      "version": "1.6.3",
+      "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+      "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.0.0"
+      }
+    },
+    "node_modules/@material/mwc-icon/node_modules/lit": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+      "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+      "dependencies": {
+        "@lit/reactive-element": "^1.6.0",
+        "lit-element": "^3.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/@material/mwc-icon/node_modules/lit-element": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+      "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.1.0",
+        "@lit/reactive-element": "^1.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/@material/mwc-icon/node_modules/lit-html": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+      "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+      "dependencies": {
+        "@types/trusted-types": "^2.0.2"
+      }
+    },
     "node_modules/@material/mwc-line-ripple": {
       "version": "0.27.0",
       "resolved": "https://registry.npmjs.org/@material/mwc-line-ripple/-/mwc-line-ripple-0.27.0.tgz",
@@ -915,6 +1174,42 @@
         "tslib": "^2.0.1"
       }
     },
+    "node_modules/@material/mwc-line-ripple/node_modules/@lit/reactive-element": {
+      "version": "1.6.3",
+      "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+      "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.0.0"
+      }
+    },
+    "node_modules/@material/mwc-line-ripple/node_modules/lit": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+      "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+      "dependencies": {
+        "@lit/reactive-element": "^1.6.0",
+        "lit-element": "^3.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/@material/mwc-line-ripple/node_modules/lit-element": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+      "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.1.0",
+        "@lit/reactive-element": "^1.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/@material/mwc-line-ripple/node_modules/lit-html": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+      "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+      "dependencies": {
+        "@types/trusted-types": "^2.0.2"
+      }
+    },
     "node_modules/@material/mwc-list": {
       "version": "0.27.0",
       "resolved": "https://registry.npmjs.org/@material/mwc-list/-/mwc-list-0.27.0.tgz",
@@ -931,6 +1226,42 @@
         "tslib": "^2.0.1"
       }
     },
+    "node_modules/@material/mwc-list/node_modules/@lit/reactive-element": {
+      "version": "1.6.3",
+      "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+      "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.0.0"
+      }
+    },
+    "node_modules/@material/mwc-list/node_modules/lit": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+      "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+      "dependencies": {
+        "@lit/reactive-element": "^1.6.0",
+        "lit-element": "^3.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/@material/mwc-list/node_modules/lit-element": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+      "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.1.0",
+        "@lit/reactive-element": "^1.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/@material/mwc-list/node_modules/lit-html": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+      "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+      "dependencies": {
+        "@types/trusted-types": "^2.0.2"
+      }
+    },
     "node_modules/@material/mwc-menu": {
       "version": "0.27.0",
       "resolved": "https://registry.npmjs.org/@material/mwc-menu/-/mwc-menu-0.27.0.tgz",
@@ -946,6 +1277,42 @@
         "tslib": "^2.0.1"
       }
     },
+    "node_modules/@material/mwc-menu/node_modules/@lit/reactive-element": {
+      "version": "1.6.3",
+      "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+      "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.0.0"
+      }
+    },
+    "node_modules/@material/mwc-menu/node_modules/lit": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+      "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+      "dependencies": {
+        "@lit/reactive-element": "^1.6.0",
+        "lit-element": "^3.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/@material/mwc-menu/node_modules/lit-element": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+      "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.1.0",
+        "@lit/reactive-element": "^1.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/@material/mwc-menu/node_modules/lit-html": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+      "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+      "dependencies": {
+        "@types/trusted-types": "^2.0.2"
+      }
+    },
     "node_modules/@material/mwc-notched-outline": {
       "version": "0.27.0",
       "resolved": "https://registry.npmjs.org/@material/mwc-notched-outline/-/mwc-notched-outline-0.27.0.tgz",
@@ -957,6 +1324,42 @@
         "tslib": "^2.0.1"
       }
     },
+    "node_modules/@material/mwc-notched-outline/node_modules/@lit/reactive-element": {
+      "version": "1.6.3",
+      "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+      "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.0.0"
+      }
+    },
+    "node_modules/@material/mwc-notched-outline/node_modules/lit": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+      "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+      "dependencies": {
+        "@lit/reactive-element": "^1.6.0",
+        "lit-element": "^3.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/@material/mwc-notched-outline/node_modules/lit-element": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+      "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.1.0",
+        "@lit/reactive-element": "^1.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/@material/mwc-notched-outline/node_modules/lit-html": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+      "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+      "dependencies": {
+        "@types/trusted-types": "^2.0.2"
+      }
+    },
     "node_modules/@material/mwc-radio": {
       "version": "0.27.0",
       "resolved": "https://registry.npmjs.org/@material/mwc-radio/-/mwc-radio-0.27.0.tgz",
@@ -969,6 +1372,42 @@
         "tslib": "^2.0.1"
       }
     },
+    "node_modules/@material/mwc-radio/node_modules/@lit/reactive-element": {
+      "version": "1.6.3",
+      "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+      "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.0.0"
+      }
+    },
+    "node_modules/@material/mwc-radio/node_modules/lit": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+      "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+      "dependencies": {
+        "@lit/reactive-element": "^1.6.0",
+        "lit-element": "^3.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/@material/mwc-radio/node_modules/lit-element": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+      "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.1.0",
+        "@lit/reactive-element": "^1.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/@material/mwc-radio/node_modules/lit-html": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+      "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+      "dependencies": {
+        "@types/trusted-types": "^2.0.2"
+      }
+    },
     "node_modules/@material/mwc-ripple": {
       "version": "0.27.0",
       "resolved": "https://registry.npmjs.org/@material/mwc-ripple/-/mwc-ripple-0.27.0.tgz",
@@ -981,6 +1420,42 @@
         "tslib": "^2.0.1"
       }
     },
+    "node_modules/@material/mwc-ripple/node_modules/@lit/reactive-element": {
+      "version": "1.6.3",
+      "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+      "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.0.0"
+      }
+    },
+    "node_modules/@material/mwc-ripple/node_modules/lit": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+      "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+      "dependencies": {
+        "@lit/reactive-element": "^1.6.0",
+        "lit-element": "^3.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/@material/mwc-ripple/node_modules/lit-element": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+      "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.1.0",
+        "@lit/reactive-element": "^1.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/@material/mwc-ripple/node_modules/lit-html": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+      "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+      "dependencies": {
+        "@types/trusted-types": "^2.0.2"
+      }
+    },
     "node_modules/@material/mwc-select": {
       "version": "0.27.0",
       "resolved": "https://registry.npmjs.org/@material/mwc-select/-/mwc-select-0.27.0.tgz",
@@ -1002,20 +1477,92 @@
         "tslib": "^2.0.1"
       }
     },
-    "node_modules/@material/mwc-textfield": {
-      "version": "0.27.0",
-      "resolved": "https://registry.npmjs.org/@material/mwc-textfield/-/mwc-textfield-0.27.0.tgz",
-      "integrity": "sha512-4/OEeEVAWWQ1DzpjeMLYLsa9HMlifOPjAvi0681Yj1g/RYJs5ONZS80HZ8HOT+efAOlZDugshgM4gdNS3I0XFQ==",
+    "node_modules/@material/mwc-select/node_modules/@lit/reactive-element": {
+      "version": "1.6.3",
+      "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+      "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.0.0"
+      }
+    },
+    "node_modules/@material/mwc-select/node_modules/lit": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+      "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+      "dependencies": {
+        "@lit/reactive-element": "^1.6.0",
+        "lit-element": "^3.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/@material/mwc-select/node_modules/lit-element": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+      "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.1.0",
+        "@lit/reactive-element": "^1.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/@material/mwc-select/node_modules/lit-html": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+      "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+      "dependencies": {
+        "@types/trusted-types": "^2.0.2"
+      }
+    },
+    "node_modules/@material/mwc-textfield": {
+      "version": "0.27.0",
+      "resolved": "https://registry.npmjs.org/@material/mwc-textfield/-/mwc-textfield-0.27.0.tgz",
+      "integrity": "sha512-4/OEeEVAWWQ1DzpjeMLYLsa9HMlifOPjAvi0681Yj1g/RYJs5ONZS80HZ8HOT+efAOlZDugshgM4gdNS3I0XFQ==",
+      "dependencies": {
+        "@material/floating-label": "=14.0.0-canary.53b3cad2f.0",
+        "@material/line-ripple": "=14.0.0-canary.53b3cad2f.0",
+        "@material/mwc-base": "^0.27.0",
+        "@material/mwc-floating-label": "^0.27.0",
+        "@material/mwc-line-ripple": "^0.27.0",
+        "@material/mwc-notched-outline": "^0.27.0",
+        "@material/textfield": "=14.0.0-canary.53b3cad2f.0",
+        "lit": "^2.0.0",
+        "tslib": "^2.0.1"
+      }
+    },
+    "node_modules/@material/mwc-textfield/node_modules/@lit/reactive-element": {
+      "version": "1.6.3",
+      "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+      "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.0.0"
+      }
+    },
+    "node_modules/@material/mwc-textfield/node_modules/lit": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+      "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+      "dependencies": {
+        "@lit/reactive-element": "^1.6.0",
+        "lit-element": "^3.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/@material/mwc-textfield/node_modules/lit-element": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+      "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.1.0",
+        "@lit/reactive-element": "^1.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/@material/mwc-textfield/node_modules/lit-html": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+      "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
       "dependencies": {
-        "@material/floating-label": "=14.0.0-canary.53b3cad2f.0",
-        "@material/line-ripple": "=14.0.0-canary.53b3cad2f.0",
-        "@material/mwc-base": "^0.27.0",
-        "@material/mwc-floating-label": "^0.27.0",
-        "@material/mwc-line-ripple": "^0.27.0",
-        "@material/mwc-notched-outline": "^0.27.0",
-        "@material/textfield": "=14.0.0-canary.53b3cad2f.0",
-        "lit": "^2.0.0",
-        "tslib": "^2.0.1"
+        "@types/trusted-types": "^2.0.2"
       }
     },
     "node_modules/@material/notched-outline": {
@@ -1167,6 +1714,15 @@
         "tslib": "^2.1.0"
       }
     },
+    "node_modules/@material/web": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@material/web/-/web-1.2.0.tgz",
+      "integrity": "sha512-1+s9J7K2wtZid8HpNstGoFwNFE0/4bXgSYZx2Hy01aZL/8oOMZ6rN733onTJMgf3zz9xKizDQUscxB28ZtkDFQ==",
+      "dependencies": {
+        "lit": "^2.7.4 || ^3.0.0",
+        "tslib": "^2.4.0"
+      }
+    },
     "node_modules/@rollup/plugin-babel": {
       "version": "6.0.4",
       "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-6.0.4.tgz",
@@ -1193,6 +1749,31 @@
         }
       }
     },
+    "node_modules/@rollup/plugin-commonjs": {
+      "version": "25.0.7",
+      "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.7.tgz",
+      "integrity": "sha512-nEvcR+LRjEjsaSsc4x3XZfCCvZIaSMenZu/OiwOKGN2UhQpAYI7ru7czFvyWbErlpoGjnSX3D5Ch5FcMA3kRWQ==",
+      "dev": true,
+      "dependencies": {
+        "@rollup/pluginutils": "^5.0.1",
+        "commondir": "^1.0.1",
+        "estree-walker": "^2.0.2",
+        "glob": "^8.0.3",
+        "is-reference": "1.2.1",
+        "magic-string": "^0.30.3"
+      },
+      "engines": {
+        "node": ">=14.0.0"
+      },
+      "peerDependencies": {
+        "rollup": "^2.68.0||^3.0.0||^4.0.0"
+      },
+      "peerDependenciesMeta": {
+        "rollup": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/@rollup/plugin-json": {
       "version": "6.1.0",
       "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.1.0.tgz",
@@ -1309,9 +1890,9 @@
       }
     },
     "node_modules/@rollup/rollup-android-arm-eabi": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.6.tgz",
-      "integrity": "sha512-MVNXSSYN6QXOulbHpLMKYi60ppyO13W9my1qogeiAqtjb2yR4LSmfU2+POvDkLzhjYLXz9Rf9+9a3zFHW1Lecg==",
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.10.0.tgz",
+      "integrity": "sha512-/MeDQmcD96nVoRumKUljsYOLqfv1YFJps+0pTrb2Z9Nl/w5qNUysMaWQsrd1mvAlNT4yza1iVyIu4Q4AgF6V3A==",
       "cpu": [
         "arm"
       ],
@@ -1322,9 +1903,9 @@
       ]
     },
     "node_modules/@rollup/rollup-android-arm64": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.9.6.tgz",
-      "integrity": "sha512-T14aNLpqJ5wzKNf5jEDpv5zgyIqcpn1MlwCrUXLrwoADr2RkWA0vOWP4XxbO9aiO3dvMCQICZdKeDrFl7UMClw==",
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.10.0.tgz",
+      "integrity": "sha512-lvu0jK97mZDJdpZKDnZI93I0Om8lSDaiPx3OiCk0RXn3E8CMPJNS/wxjAvSJJzhhZpfjXsjLWL8LnS6qET4VNQ==",
       "cpu": [
         "arm64"
       ],
@@ -1335,9 +1916,9 @@
       ]
     },
     "node_modules/@rollup/rollup-darwin-arm64": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.9.6.tgz",
-      "integrity": "sha512-CqNNAyhRkTbo8VVZ5R85X73H3R5NX9ONnKbXuHisGWC0qRbTTxnF1U4V9NafzJbgGM0sHZpdO83pLPzq8uOZFw==",
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.10.0.tgz",
+      "integrity": "sha512-uFpayx8I8tyOvDkD7X6n0PriDRWxcqEjqgtlxnUA/G9oS93ur9aZ8c8BEpzFmsed1TH5WZNG5IONB8IiW90TQg==",
       "cpu": [
         "arm64"
       ],
@@ -1348,9 +1929,9 @@
       ]
     },
     "node_modules/@rollup/rollup-darwin-x64": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.9.6.tgz",
-      "integrity": "sha512-zRDtdJuRvA1dc9Mp6BWYqAsU5oeLixdfUvkTHuiYOHwqYuQ4YgSmi6+/lPvSsqc/I0Omw3DdICx4Tfacdzmhog==",
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.10.0.tgz",
+      "integrity": "sha512-nIdCX03qFKoR/MwQegQBK+qZoSpO3LESurVAC6s6jazLA1Mpmgzo3Nj3H1vydXp/JM29bkCiuF7tDuToj4+U9Q==",
       "cpu": [
         "x64"
       ],
@@ -1361,9 +1942,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.9.6.tgz",
-      "integrity": "sha512-oNk8YXDDnNyG4qlNb6is1ojTOGL/tRhbbKeE/YuccItzerEZT68Z9gHrY3ROh7axDc974+zYAPxK5SH0j/G+QQ==",
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.10.0.tgz",
+      "integrity": "sha512-Fz7a+y5sYhYZMQFRkOyCs4PLhICAnxRX/GnWYReaAoruUzuRtcf+Qnw+T0CoAWbHCuz2gBUwmWnUgQ67fb3FYw==",
       "cpu": [
         "arm"
       ],
@@ -1374,9 +1955,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-arm64-gnu": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.9.6.tgz",
-      "integrity": "sha512-Z3O60yxPtuCYobrtzjo0wlmvDdx2qZfeAWTyfOjEDqd08kthDKexLpV97KfAeUXPosENKd8uyJMRDfFMxcYkDQ==",
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.10.0.tgz",
+      "integrity": "sha512-yPtF9jIix88orwfTi0lJiqINnlWo6p93MtZEoaehZnmCzEmLL0eqjA3eGVeyQhMtxdV+Mlsgfwhh0+M/k1/V7Q==",
       "cpu": [
         "arm64"
       ],
@@ -1387,9 +1968,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-arm64-musl": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.9.6.tgz",
-      "integrity": "sha512-gpiG0qQJNdYEVad+1iAsGAbgAnZ8j07FapmnIAQgODKcOTjLEWM9sRb+MbQyVsYCnA0Im6M6QIq6ax7liws6eQ==",
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.10.0.tgz",
+      "integrity": "sha512-9GW9yA30ib+vfFiwjX+N7PnjTnCMiUffhWj4vkG4ukYv1kJ4T9gHNg8zw+ChsOccM27G9yXrEtMScf1LaCuoWQ==",
       "cpu": [
         "arm64"
       ],
@@ -1400,9 +1981,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-riscv64-gnu": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.9.6.tgz",
-      "integrity": "sha512-+uCOcvVmFUYvVDr27aiyun9WgZk0tXe7ThuzoUTAukZJOwS5MrGbmSlNOhx1j80GdpqbOty05XqSl5w4dQvcOA==",
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.10.0.tgz",
+      "integrity": "sha512-X1ES+V4bMq2ws5fF4zHornxebNxMXye0ZZjUrzOrf7UMx1d6wMQtfcchZ8SqUnQPPHdOyOLW6fTcUiFgHFadRA==",
       "cpu": [
         "riscv64"
       ],
@@ -1413,9 +1994,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-x64-gnu": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.9.6.tgz",
-      "integrity": "sha512-HUNqM32dGzfBKuaDUBqFB7tP6VMN74eLZ33Q9Y1TBqRDn+qDonkAUyKWwF9BR9unV7QUzffLnz9GrnKvMqC/fw==",
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.10.0.tgz",
+      "integrity": "sha512-w/5OpT2EnI/Xvypw4FIhV34jmNqU5PZjZue2l2Y3ty1Ootm3SqhI+AmfhlUYGBTd9JnpneZCDnt3uNOiOBkMyw==",
       "cpu": [
         "x64"
       ],
@@ -1426,9 +2007,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-x64-musl": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.9.6.tgz",
-      "integrity": "sha512-ch7M+9Tr5R4FK40FHQk8VnML0Szi2KRujUgHXd/HjuH9ifH72GUmw6lStZBo3c3GB82vHa0ZoUfjfcM7JiiMrQ==",
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.10.0.tgz",
+      "integrity": "sha512-q/meftEe3QlwQiGYxD9rWwB21DoKQ9Q8wA40of/of6yGHhZuGfZO0c3WYkN9dNlopHlNT3mf5BPsUSxoPuVQaw==",
       "cpu": [
         "x64"
       ],
@@ -1439,9 +2020,9 @@
       ]
     },
     "node_modules/@rollup/rollup-win32-arm64-msvc": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.9.6.tgz",
-      "integrity": "sha512-VD6qnR99dhmTQ1mJhIzXsRcTBvTjbfbGGwKAHcu+52cVl15AC/kplkhxzW/uT0Xl62Y/meBKDZvoJSJN+vTeGA==",
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.10.0.tgz",
+      "integrity": "sha512-NrR6667wlUfP0BHaEIKgYM/2va+Oj+RjZSASbBMnszM9k+1AmliRjHc3lJIiOehtSSjqYiO7R6KLNrWOX+YNSQ==",
       "cpu": [
         "arm64"
       ],
@@ -1452,9 +2033,9 @@
       ]
     },
     "node_modules/@rollup/rollup-win32-ia32-msvc": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.9.6.tgz",
-      "integrity": "sha512-J9AFDq/xiRI58eR2NIDfyVmTYGyIZmRcvcAoJ48oDld/NTR8wyiPUu2X/v1navJ+N/FGg68LEbX3Ejd6l8B7MQ==",
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.10.0.tgz",
+      "integrity": "sha512-FV0Tpt84LPYDduIDcXvEC7HKtyXxdvhdAOvOeWMWbQNulxViH2O07QXkT/FffX4FqEI02jEbCJbr+YcuKdyyMg==",
       "cpu": [
         "ia32"
       ],
@@ -1465,9 +2046,9 @@
       ]
     },
     "node_modules/@rollup/rollup-win32-x64-msvc": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.9.6.tgz",
-      "integrity": "sha512-jqzNLhNDvIZOrt69Ce4UjGRpXJBzhUBzawMwnaDAwyHriki3XollsewxWzOzz+4yOFDkuJHtTsZFwMxhYJWmLQ==",
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.10.0.tgz",
+      "integrity": "sha512-OZoJd+o5TaTSQeFFQ6WjFCiltiYVjIdsXxwu/XZ8qRpsvMQr4UsVrE5UyT9RIvsnuF47DqkJKhhVZ2Q9YW9IpQ==",
       "cpu": [
         "x64"
       ],
@@ -1490,9 +2071,9 @@
       "dev": true
     },
     "node_modules/@types/trusted-types": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.3.tgz",
-      "integrity": "sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g=="
+      "version": "2.0.7",
+      "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
+      "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="
     },
     "node_modules/@types/w3c-web-serial": {
       "version": "1.0.6",
@@ -1665,6 +2246,25 @@
       "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
       "dev": true
     },
+    "node_modules/base64-js": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ]
+    },
     "node_modules/blocking-elements": {
       "version": "0.1.1",
       "license": "Apache-2.0"
@@ -1742,6 +2342,29 @@
         "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
       }
     },
+    "node_modules/buffer": {
+      "version": "6.0.3",
+      "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
+      "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "dependencies": {
+        "base64-js": "^1.3.1",
+        "ieee754": "^1.2.1"
+      }
+    },
     "node_modules/buffer-from": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
@@ -1946,6 +2569,12 @@
       "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
       "dev": true
     },
+    "node_modules/commondir": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
+      "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==",
+      "dev": true
+    },
     "node_modules/compressible": {
       "version": "2.0.18",
       "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
@@ -2083,10 +2712,11 @@
       }
     },
     "node_modules/esptool-js": {
-      "version": "0.3.2",
-      "resolved": "https://registry.npmjs.org/esptool-js/-/esptool-js-0.3.2.tgz",
-      "integrity": "sha512-hA58j6wxm143MTa1ZkM/uaDsaF2U+/2sdcoPVz5G78o7wENqzOb5KnHfhPGXK8mbhhYnmC7JXGhZ7wfgeB8DmQ==",
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/esptool-js/-/esptool-js-0.4.1.tgz",
+      "integrity": "sha512-JhPHyjBncwnZDmOWxzjCQV5e6m1qP9kXPsZy5Zn/cu4tBOfPL8McncIzNVCzmLn7Jvgi06Jg09OK2HrkyMSboA==",
       "dependencies": {
+        "buffer": "^6.0.3",
         "pako": "^2.1.0",
         "tslib": "^2.4.1"
       }
@@ -2135,6 +2765,12 @@
         "punycode": "^1.3.2"
       }
     },
+    "node_modules/fs.realpath": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+      "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+      "dev": true
+    },
     "node_modules/fsevents": {
       "version": "2.3.2",
       "dev": true,
@@ -2175,6 +2811,46 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/glob": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
+      "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
+      "dev": true,
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^5.0.1",
+        "once": "^1.3.0"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/glob/node_modules/brace-expansion": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+      "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+      "dev": true,
+      "dependencies": {
+        "balanced-match": "^1.0.0"
+      }
+    },
+    "node_modules/glob/node_modules/minimatch": {
+      "version": "5.1.6",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
+      "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/globals": {
       "version": "11.12.0",
       "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
@@ -2214,6 +2890,25 @@
         "node": ">=10.17.0"
       }
     },
+    "node_modules/ieee754": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+      "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ]
+    },
     "node_modules/improv-wifi-serial-sdk": {
       "version": "2.5.0",
       "resolved": "https://registry.npmjs.org/improv-wifi-serial-sdk/-/improv-wifi-serial-sdk-2.5.0.tgz",
@@ -2230,6 +2925,58 @@
         "tslib": "^2.4.1"
       }
     },
+    "node_modules/improv-wifi-serial-sdk/node_modules/@lit/reactive-element": {
+      "version": "1.6.3",
+      "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+      "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.0.0"
+      }
+    },
+    "node_modules/improv-wifi-serial-sdk/node_modules/lit": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+      "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+      "dependencies": {
+        "@lit/reactive-element": "^1.6.0",
+        "lit-element": "^3.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/improv-wifi-serial-sdk/node_modules/lit-element": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+      "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.1.0",
+        "@lit/reactive-element": "^1.3.0",
+        "lit-html": "^2.8.0"
+      }
+    },
+    "node_modules/improv-wifi-serial-sdk/node_modules/lit-html": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+      "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+      "dependencies": {
+        "@types/trusted-types": "^2.0.2"
+      }
+    },
+    "node_modules/inflight": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+      "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+      "dev": true,
+      "dependencies": {
+        "once": "^1.3.0",
+        "wrappy": "1"
+      }
+    },
+    "node_modules/inherits": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+      "dev": true
+    },
     "node_modules/ini": {
       "version": "1.3.8",
       "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
@@ -2304,6 +3051,15 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/is-reference": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz",
+      "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/estree": "*"
+      }
+    },
     "node_modules/is-stream": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
@@ -2372,29 +3128,29 @@
       }
     },
     "node_modules/lit": {
-      "version": "2.8.0",
-      "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
-      "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/lit/-/lit-3.1.2.tgz",
+      "integrity": "sha512-VZx5iAyMtX7CV4K8iTLdCkMaYZ7ipjJZ0JcSdJ0zIdGxxyurjIn7yuuSxNBD7QmjvcNJwr0JS4cAdAtsy7gZ6w==",
       "dependencies": {
-        "@lit/reactive-element": "^1.6.0",
-        "lit-element": "^3.3.0",
-        "lit-html": "^2.8.0"
+        "@lit/reactive-element": "^2.0.4",
+        "lit-element": "^4.0.4",
+        "lit-html": "^3.1.2"
       }
     },
     "node_modules/lit-element": {
-      "version": "3.3.2",
-      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.2.tgz",
-      "integrity": "sha512-xXAeVWKGr4/njq0rGC9dethMnYCq5hpKYrgQZYTzawt9YQhMiXfD+T1RgrdY3NamOxwq2aXlb0vOI6e29CKgVQ==",
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.0.4.tgz",
+      "integrity": "sha512-98CvgulX6eCPs6TyAIQoJZBCQPo80rgXR+dVBs61cstJXqtI+USQZAbA4gFHh6L/mxBx9MrgPLHLsUgDUHAcCQ==",
       "dependencies": {
-        "@lit-labs/ssr-dom-shim": "^1.1.0",
-        "@lit/reactive-element": "^1.3.0",
-        "lit-html": "^2.7.0"
+        "@lit-labs/ssr-dom-shim": "^1.2.0",
+        "@lit/reactive-element": "^2.0.4",
+        "lit-html": "^3.1.2"
       }
     },
     "node_modules/lit-html": {
-      "version": "2.8.0",
-      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
-      "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.1.2.tgz",
+      "integrity": "sha512-3OBZSUrPnAHoKJ9AMjRL/m01YJxQMf+TMHanNtTHG68ubjnZxK0RFl102DPzsw4mWnHibfZIBJm3LWCZ/LmMvg==",
       "dependencies": {
         "@types/trusted-types": "^2.0.2"
       }
@@ -2409,6 +3165,18 @@
         "yallist": "^3.0.2"
       }
     },
+    "node_modules/magic-string": {
+      "version": "0.30.7",
+      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.7.tgz",
+      "integrity": "sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==",
+      "dev": true,
+      "dependencies": {
+        "@jridgewell/sourcemap-codec": "^1.4.15"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
     "node_modules/merge-stream": {
       "version": "2.0.0",
       "dev": true,
@@ -2514,6 +3282,15 @@
         "node": ">= 0.8"
       }
     },
+    "node_modules/once": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+      "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+      "dev": true,
+      "dependencies": {
+        "wrappy": "1"
+      }
+    },
     "node_modules/onetime": {
       "version": "5.1.2",
       "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
@@ -2581,9 +3358,9 @@
       }
     },
     "node_modules/prettier": {
-      "version": "3.2.4",
-      "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.4.tgz",
-      "integrity": "sha512-FWu1oLHKCrtpO1ypU6J0SbK2d9Ckwysq6bHj/uaCP26DxrPpppCLQRGVuqAxSTvhF00AcvDRyYrLNW7ocBhFFQ==",
+      "version": "3.2.5",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz",
+      "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==",
       "dev": true,
       "bin": {
         "prettier": "bin/prettier.cjs"
@@ -2683,9 +3460,9 @@
       }
     },
     "node_modules/rollup": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.9.6.tgz",
-      "integrity": "sha512-05lzkCS2uASX0CiLFybYfVkwNbKZG5NFQ6Go0VWyogFTXXbR039UVsegViTntkk4OglHBdF54ccApXRRuXRbsg==",
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.10.0.tgz",
+      "integrity": "sha512-t2v9G2AKxcQ8yrG+WGxctBes1AomT0M4ND7jTFBCVPXQ/WFTvNSefIrNSmLKhIKBrvN8SG+CZslimJcT3W2u2g==",
       "dev": true,
       "dependencies": {
         "@types/estree": "1.0.5"
@@ -2698,19 +3475,19 @@
         "npm": ">=8.0.0"
       },
       "optionalDependencies": {
-        "@rollup/rollup-android-arm-eabi": "4.9.6",
-        "@rollup/rollup-android-arm64": "4.9.6",
-        "@rollup/rollup-darwin-arm64": "4.9.6",
-        "@rollup/rollup-darwin-x64": "4.9.6",
-        "@rollup/rollup-linux-arm-gnueabihf": "4.9.6",
-        "@rollup/rollup-linux-arm64-gnu": "4.9.6",
-        "@rollup/rollup-linux-arm64-musl": "4.9.6",
-        "@rollup/rollup-linux-riscv64-gnu": "4.9.6",
-        "@rollup/rollup-linux-x64-gnu": "4.9.6",
-        "@rollup/rollup-linux-x64-musl": "4.9.6",
-        "@rollup/rollup-win32-arm64-msvc": "4.9.6",
-        "@rollup/rollup-win32-ia32-msvc": "4.9.6",
-        "@rollup/rollup-win32-x64-msvc": "4.9.6",
+        "@rollup/rollup-android-arm-eabi": "4.10.0",
+        "@rollup/rollup-android-arm64": "4.10.0",
+        "@rollup/rollup-darwin-arm64": "4.10.0",
+        "@rollup/rollup-darwin-x64": "4.10.0",
+        "@rollup/rollup-linux-arm-gnueabihf": "4.10.0",
+        "@rollup/rollup-linux-arm64-gnu": "4.10.0",
+        "@rollup/rollup-linux-arm64-musl": "4.10.0",
+        "@rollup/rollup-linux-riscv64-gnu": "4.10.0",
+        "@rollup/rollup-linux-x64-gnu": "4.10.0",
+        "@rollup/rollup-linux-x64-musl": "4.10.0",
+        "@rollup/rollup-win32-arm64-msvc": "4.10.0",
+        "@rollup/rollup-win32-ia32-msvc": "4.10.0",
+        "@rollup/rollup-win32-x64-msvc": "4.10.0",
         "fsevents": "~2.3.2"
       }
     },
@@ -3114,6 +3891,12 @@
         "url": "https://github.com/chalk/ansi-styles?sponsor=1"
       }
     },
+    "node_modules/wrappy": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+      "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+      "dev": true
+    },
     "node_modules/yallist": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
@@ -3524,9 +4307,9 @@
       }
     },
     "@jridgewell/sourcemap-codec": {
-      "version": "1.4.14",
-      "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
-      "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
+      "version": "1.4.15",
+      "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
+      "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
       "dev": true
     },
     "@jridgewell/trace-mapping": {
@@ -3540,16 +4323,16 @@
       }
     },
     "@lit-labs/ssr-dom-shim": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.1.1.tgz",
-      "integrity": "sha512-kXOeFbfCm4fFf2A3WwVEeQj55tMZa8c8/f9AKHMobQMkzNUfUj+antR3fRPaZJawsa1aZiP/Da3ndpZrwEe4rQ=="
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.2.0.tgz",
+      "integrity": "sha512-yWJKmpGE6lUURKAaIltoPIE/wrbY3TEkqQt+X0m+7fQNnAv0keydnYvbiJFP1PnMhizmIWRWOG5KLhYyc/xl+g=="
     },
     "@lit/reactive-element": {
-      "version": "1.6.2",
-      "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.2.tgz",
-      "integrity": "sha512-rDfl+QnCYjuIGf5xI2sVJWdYIi56CTCwWa+nidKYX6oIuBYwUbT/vX4qbUDlHiZKJ/3FRNQ/tWJui44p6/stSA==",
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.0.4.tgz",
+      "integrity": "sha512-GFn91inaUa2oHLak8awSIigYz0cU0Payr1rcFsrkf5OJ5eSPxElyZfKh0f2p9FsTiZWXQdWGJeXZICEfXXYSXQ==",
       "requires": {
-        "@lit-labs/ssr-dom-shim": "^1.0.0"
+        "@lit-labs/ssr-dom-shim": "^1.2.0"
       }
     },
     "@material/animation": {
@@ -3665,18 +4448,6 @@
         "@material/rtl": "14.0.0-canary.53b3cad2f.0"
       }
     },
-    "@material/form-field": {
-      "version": "14.0.0-canary.53b3cad2f.0",
-      "requires": {
-        "@material/base": "14.0.0-canary.53b3cad2f.0",
-        "@material/feature-targeting": "14.0.0-canary.53b3cad2f.0",
-        "@material/ripple": "14.0.0-canary.53b3cad2f.0",
-        "@material/rtl": "14.0.0-canary.53b3cad2f.0",
-        "@material/theme": "14.0.0-canary.53b3cad2f.0",
-        "@material/typography": "14.0.0-canary.53b3cad2f.0",
-        "tslib": "^2.1.0"
-      }
-    },
     "@material/icon-button": {
       "version": "14.0.0-canary.53b3cad2f.0",
       "requires": {
@@ -3761,6 +4532,44 @@
         "@material/dom": "=14.0.0-canary.53b3cad2f.0",
         "lit": "^2.0.0",
         "tslib": "^2.0.1"
+      },
+      "dependencies": {
+        "@lit/reactive-element": {
+          "version": "1.6.3",
+          "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+          "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.0.0"
+          }
+        },
+        "lit": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+          "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+          "requires": {
+            "@lit/reactive-element": "^1.6.0",
+            "lit-element": "^3.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-element": {
+          "version": "3.3.3",
+          "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+          "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.1.0",
+            "@lit/reactive-element": "^1.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-html": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+          "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+          "requires": {
+            "@types/trusted-types": "^2.0.2"
+          }
+        }
       }
     },
     "@material/mwc-button": {
@@ -3772,6 +4581,44 @@
         "@material/mwc-ripple": "^0.27.0",
         "lit": "^2.0.0",
         "tslib": "^2.0.1"
+      },
+      "dependencies": {
+        "@lit/reactive-element": {
+          "version": "1.6.3",
+          "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+          "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.0.0"
+          }
+        },
+        "lit": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+          "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+          "requires": {
+            "@lit/reactive-element": "^1.6.0",
+            "lit-element": "^3.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-element": {
+          "version": "3.3.3",
+          "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+          "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.1.0",
+            "@lit/reactive-element": "^1.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-html": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+          "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+          "requires": {
+            "@types/trusted-types": "^2.0.2"
+          }
+        }
       }
     },
     "@material/mwc-checkbox": {
@@ -3783,6 +4630,44 @@
         "@material/mwc-ripple": "^0.27.0",
         "lit": "^2.0.0",
         "tslib": "^2.0.1"
+      },
+      "dependencies": {
+        "@lit/reactive-element": {
+          "version": "1.6.3",
+          "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+          "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.0.0"
+          }
+        },
+        "lit": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+          "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+          "requires": {
+            "@lit/reactive-element": "^1.6.0",
+            "lit-element": "^3.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-element": {
+          "version": "3.3.3",
+          "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+          "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.1.0",
+            "@lit/reactive-element": "^1.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-html": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+          "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+          "requires": {
+            "@types/trusted-types": "^2.0.2"
+          }
+        }
       }
     },
     "@material/mwc-circular-progress": {
@@ -3795,6 +4680,44 @@
         "@material/theme": "=14.0.0-canary.53b3cad2f.0",
         "lit": "^2.0.0",
         "tslib": "^2.0.1"
+      },
+      "dependencies": {
+        "@lit/reactive-element": {
+          "version": "1.6.3",
+          "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+          "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.0.0"
+          }
+        },
+        "lit": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+          "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+          "requires": {
+            "@lit/reactive-element": "^1.6.0",
+            "lit-element": "^3.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-element": {
+          "version": "3.3.3",
+          "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+          "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.1.0",
+            "@lit/reactive-element": "^1.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-html": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+          "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+          "requires": {
+            "@types/trusted-types": "^2.0.2"
+          }
+        }
       }
     },
     "@material/mwc-dialog": {
@@ -3810,6 +4733,44 @@
         "lit": "^2.0.0",
         "tslib": "^2.0.1",
         "wicg-inert": "^3.0.0"
+      },
+      "dependencies": {
+        "@lit/reactive-element": {
+          "version": "1.6.3",
+          "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+          "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.0.0"
+          }
+        },
+        "lit": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+          "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+          "requires": {
+            "@lit/reactive-element": "^1.6.0",
+            "lit-element": "^3.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-element": {
+          "version": "3.3.3",
+          "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+          "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.1.0",
+            "@lit/reactive-element": "^1.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-html": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+          "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+          "requires": {
+            "@types/trusted-types": "^2.0.2"
+          }
+        }
       }
     },
     "@material/mwc-floating-label": {
@@ -3820,17 +4781,44 @@
         "@material/floating-label": "=14.0.0-canary.53b3cad2f.0",
         "lit": "^2.0.0",
         "tslib": "^2.0.1"
-      }
-    },
-    "@material/mwc-formfield": {
-      "version": "0.27.0",
-      "resolved": "https://registry.npmjs.org/@material/mwc-formfield/-/mwc-formfield-0.27.0.tgz",
-      "integrity": "sha512-XGZtC1MTyGQ8b2osnaygGzS3qe2QvlWfXZepcFs9i6MW+b6VimQQ4c/KsKIF7dHmeY6N0o4k9pAZ086EGesXOQ==",
-      "requires": {
-        "@material/form-field": "=14.0.0-canary.53b3cad2f.0",
-        "@material/mwc-base": "^0.27.0",
-        "lit": "^2.0.0",
-        "tslib": "^2.0.1"
+      },
+      "dependencies": {
+        "@lit/reactive-element": {
+          "version": "1.6.3",
+          "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+          "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.0.0"
+          }
+        },
+        "lit": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+          "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+          "requires": {
+            "@lit/reactive-element": "^1.6.0",
+            "lit-element": "^3.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-element": {
+          "version": "3.3.3",
+          "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+          "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.1.0",
+            "@lit/reactive-element": "^1.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-html": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+          "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+          "requires": {
+            "@types/trusted-types": "^2.0.2"
+          }
+        }
       }
     },
     "@material/mwc-icon": {
@@ -3840,6 +4828,44 @@
       "requires": {
         "lit": "^2.0.0",
         "tslib": "^2.0.1"
+      },
+      "dependencies": {
+        "@lit/reactive-element": {
+          "version": "1.6.3",
+          "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+          "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.0.0"
+          }
+        },
+        "lit": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+          "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+          "requires": {
+            "@lit/reactive-element": "^1.6.0",
+            "lit-element": "^3.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-element": {
+          "version": "3.3.3",
+          "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+          "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.1.0",
+            "@lit/reactive-element": "^1.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-html": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+          "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+          "requires": {
+            "@types/trusted-types": "^2.0.2"
+          }
+        }
       }
     },
     "@material/mwc-icon-button": {
@@ -3850,6 +4876,44 @@
         "@material/mwc-ripple": "^0.27.0",
         "lit": "^2.0.0",
         "tslib": "^2.0.1"
+      },
+      "dependencies": {
+        "@lit/reactive-element": {
+          "version": "1.6.3",
+          "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+          "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.0.0"
+          }
+        },
+        "lit": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+          "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+          "requires": {
+            "@lit/reactive-element": "^1.6.0",
+            "lit-element": "^3.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-element": {
+          "version": "3.3.3",
+          "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+          "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.1.0",
+            "@lit/reactive-element": "^1.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-html": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+          "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+          "requires": {
+            "@types/trusted-types": "^2.0.2"
+          }
+        }
       }
     },
     "@material/mwc-line-ripple": {
@@ -3860,6 +4924,44 @@
         "@material/line-ripple": "=14.0.0-canary.53b3cad2f.0",
         "lit": "^2.0.0",
         "tslib": "^2.0.1"
+      },
+      "dependencies": {
+        "@lit/reactive-element": {
+          "version": "1.6.3",
+          "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+          "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.0.0"
+          }
+        },
+        "lit": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+          "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+          "requires": {
+            "@lit/reactive-element": "^1.6.0",
+            "lit-element": "^3.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-element": {
+          "version": "3.3.3",
+          "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+          "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.1.0",
+            "@lit/reactive-element": "^1.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-html": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+          "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+          "requires": {
+            "@types/trusted-types": "^2.0.2"
+          }
+        }
       }
     },
     "@material/mwc-list": {
@@ -3876,6 +4978,44 @@
         "@material/mwc-ripple": "^0.27.0",
         "lit": "^2.0.0",
         "tslib": "^2.0.1"
+      },
+      "dependencies": {
+        "@lit/reactive-element": {
+          "version": "1.6.3",
+          "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+          "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.0.0"
+          }
+        },
+        "lit": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+          "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+          "requires": {
+            "@lit/reactive-element": "^1.6.0",
+            "lit-element": "^3.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-element": {
+          "version": "3.3.3",
+          "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+          "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.1.0",
+            "@lit/reactive-element": "^1.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-html": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+          "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+          "requires": {
+            "@types/trusted-types": "^2.0.2"
+          }
+        }
       }
     },
     "@material/mwc-menu": {
@@ -3891,6 +5031,44 @@
         "@material/theme": "=14.0.0-canary.53b3cad2f.0",
         "lit": "^2.0.0",
         "tslib": "^2.0.1"
+      },
+      "dependencies": {
+        "@lit/reactive-element": {
+          "version": "1.6.3",
+          "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+          "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.0.0"
+          }
+        },
+        "lit": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+          "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+          "requires": {
+            "@lit/reactive-element": "^1.6.0",
+            "lit-element": "^3.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-element": {
+          "version": "3.3.3",
+          "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+          "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.1.0",
+            "@lit/reactive-element": "^1.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-html": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+          "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+          "requires": {
+            "@types/trusted-types": "^2.0.2"
+          }
+        }
       }
     },
     "@material/mwc-notched-outline": {
@@ -3902,6 +5080,44 @@
         "@material/notched-outline": "=14.0.0-canary.53b3cad2f.0",
         "lit": "^2.0.0",
         "tslib": "^2.0.1"
+      },
+      "dependencies": {
+        "@lit/reactive-element": {
+          "version": "1.6.3",
+          "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+          "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.0.0"
+          }
+        },
+        "lit": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+          "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+          "requires": {
+            "@lit/reactive-element": "^1.6.0",
+            "lit-element": "^3.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-element": {
+          "version": "3.3.3",
+          "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+          "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.1.0",
+            "@lit/reactive-element": "^1.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-html": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+          "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+          "requires": {
+            "@types/trusted-types": "^2.0.2"
+          }
+        }
       }
     },
     "@material/mwc-radio": {
@@ -3914,6 +5130,44 @@
         "@material/radio": "=14.0.0-canary.53b3cad2f.0",
         "lit": "^2.0.0",
         "tslib": "^2.0.1"
+      },
+      "dependencies": {
+        "@lit/reactive-element": {
+          "version": "1.6.3",
+          "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+          "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.0.0"
+          }
+        },
+        "lit": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+          "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+          "requires": {
+            "@lit/reactive-element": "^1.6.0",
+            "lit-element": "^3.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-element": {
+          "version": "3.3.3",
+          "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+          "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.1.0",
+            "@lit/reactive-element": "^1.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-html": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+          "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+          "requires": {
+            "@types/trusted-types": "^2.0.2"
+          }
+        }
       }
     },
     "@material/mwc-ripple": {
@@ -3926,6 +5180,44 @@
         "@material/ripple": "=14.0.0-canary.53b3cad2f.0",
         "lit": "^2.0.0",
         "tslib": "^2.0.1"
+      },
+      "dependencies": {
+        "@lit/reactive-element": {
+          "version": "1.6.3",
+          "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+          "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.0.0"
+          }
+        },
+        "lit": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+          "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+          "requires": {
+            "@lit/reactive-element": "^1.6.0",
+            "lit-element": "^3.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-element": {
+          "version": "3.3.3",
+          "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+          "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.1.0",
+            "@lit/reactive-element": "^1.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-html": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+          "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+          "requires": {
+            "@types/trusted-types": "^2.0.2"
+          }
+        }
       }
     },
     "@material/mwc-select": {
@@ -3947,6 +5239,44 @@
         "@material/select": "=14.0.0-canary.53b3cad2f.0",
         "lit": "^2.0.0",
         "tslib": "^2.0.1"
+      },
+      "dependencies": {
+        "@lit/reactive-element": {
+          "version": "1.6.3",
+          "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+          "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.0.0"
+          }
+        },
+        "lit": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+          "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+          "requires": {
+            "@lit/reactive-element": "^1.6.0",
+            "lit-element": "^3.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-element": {
+          "version": "3.3.3",
+          "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+          "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.1.0",
+            "@lit/reactive-element": "^1.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-html": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+          "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+          "requires": {
+            "@types/trusted-types": "^2.0.2"
+          }
+        }
       }
     },
     "@material/mwc-textfield": {
@@ -3963,6 +5293,44 @@
         "@material/textfield": "=14.0.0-canary.53b3cad2f.0",
         "lit": "^2.0.0",
         "tslib": "^2.0.1"
+      },
+      "dependencies": {
+        "@lit/reactive-element": {
+          "version": "1.6.3",
+          "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+          "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.0.0"
+          }
+        },
+        "lit": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+          "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+          "requires": {
+            "@lit/reactive-element": "^1.6.0",
+            "lit-element": "^3.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-element": {
+          "version": "3.3.3",
+          "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+          "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.1.0",
+            "@lit/reactive-element": "^1.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-html": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+          "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+          "requires": {
+            "@types/trusted-types": "^2.0.2"
+          }
+        }
       }
     },
     "@material/notched-outline": {
@@ -4104,6 +5472,15 @@
         "tslib": "^2.1.0"
       }
     },
+    "@material/web": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@material/web/-/web-1.2.0.tgz",
+      "integrity": "sha512-1+s9J7K2wtZid8HpNstGoFwNFE0/4bXgSYZx2Hy01aZL/8oOMZ6rN733onTJMgf3zz9xKizDQUscxB28ZtkDFQ==",
+      "requires": {
+        "lit": "^2.7.4 || ^3.0.0",
+        "tslib": "^2.4.0"
+      }
+    },
     "@rollup/plugin-babel": {
       "version": "6.0.4",
       "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-6.0.4.tgz",
@@ -4114,6 +5491,20 @@
         "@rollup/pluginutils": "^5.0.1"
       }
     },
+    "@rollup/plugin-commonjs": {
+      "version": "25.0.7",
+      "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.7.tgz",
+      "integrity": "sha512-nEvcR+LRjEjsaSsc4x3XZfCCvZIaSMenZu/OiwOKGN2UhQpAYI7ru7czFvyWbErlpoGjnSX3D5Ch5FcMA3kRWQ==",
+      "dev": true,
+      "requires": {
+        "@rollup/pluginutils": "^5.0.1",
+        "commondir": "^1.0.1",
+        "estree-walker": "^2.0.2",
+        "glob": "^8.0.3",
+        "is-reference": "1.2.1",
+        "magic-string": "^0.30.3"
+      }
+    },
     "@rollup/plugin-json": {
       "version": "6.1.0",
       "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.1.0.tgz",
@@ -4170,93 +5561,93 @@
       }
     },
     "@rollup/rollup-android-arm-eabi": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.6.tgz",
-      "integrity": "sha512-MVNXSSYN6QXOulbHpLMKYi60ppyO13W9my1qogeiAqtjb2yR4LSmfU2+POvDkLzhjYLXz9Rf9+9a3zFHW1Lecg==",
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.10.0.tgz",
+      "integrity": "sha512-/MeDQmcD96nVoRumKUljsYOLqfv1YFJps+0pTrb2Z9Nl/w5qNUysMaWQsrd1mvAlNT4yza1iVyIu4Q4AgF6V3A==",
       "dev": true,
       "optional": true
     },
     "@rollup/rollup-android-arm64": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.9.6.tgz",
-      "integrity": "sha512-T14aNLpqJ5wzKNf5jEDpv5zgyIqcpn1MlwCrUXLrwoADr2RkWA0vOWP4XxbO9aiO3dvMCQICZdKeDrFl7UMClw==",
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.10.0.tgz",
+      "integrity": "sha512-lvu0jK97mZDJdpZKDnZI93I0Om8lSDaiPx3OiCk0RXn3E8CMPJNS/wxjAvSJJzhhZpfjXsjLWL8LnS6qET4VNQ==",
       "dev": true,
       "optional": true
     },
     "@rollup/rollup-darwin-arm64": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.9.6.tgz",
-      "integrity": "sha512-CqNNAyhRkTbo8VVZ5R85X73H3R5NX9ONnKbXuHisGWC0qRbTTxnF1U4V9NafzJbgGM0sHZpdO83pLPzq8uOZFw==",
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.10.0.tgz",
+      "integrity": "sha512-uFpayx8I8tyOvDkD7X6n0PriDRWxcqEjqgtlxnUA/G9oS93ur9aZ8c8BEpzFmsed1TH5WZNG5IONB8IiW90TQg==",
       "dev": true,
       "optional": true
     },
     "@rollup/rollup-darwin-x64": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.9.6.tgz",
-      "integrity": "sha512-zRDtdJuRvA1dc9Mp6BWYqAsU5oeLixdfUvkTHuiYOHwqYuQ4YgSmi6+/lPvSsqc/I0Omw3DdICx4Tfacdzmhog==",
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.10.0.tgz",
+      "integrity": "sha512-nIdCX03qFKoR/MwQegQBK+qZoSpO3LESurVAC6s6jazLA1Mpmgzo3Nj3H1vydXp/JM29bkCiuF7tDuToj4+U9Q==",
       "dev": true,
       "optional": true
     },
     "@rollup/rollup-linux-arm-gnueabihf": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.9.6.tgz",
-      "integrity": "sha512-oNk8YXDDnNyG4qlNb6is1ojTOGL/tRhbbKeE/YuccItzerEZT68Z9gHrY3ROh7axDc974+zYAPxK5SH0j/G+QQ==",
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.10.0.tgz",
+      "integrity": "sha512-Fz7a+y5sYhYZMQFRkOyCs4PLhICAnxRX/GnWYReaAoruUzuRtcf+Qnw+T0CoAWbHCuz2gBUwmWnUgQ67fb3FYw==",
       "dev": true,
       "optional": true
     },
     "@rollup/rollup-linux-arm64-gnu": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.9.6.tgz",
-      "integrity": "sha512-Z3O60yxPtuCYobrtzjo0wlmvDdx2qZfeAWTyfOjEDqd08kthDKexLpV97KfAeUXPosENKd8uyJMRDfFMxcYkDQ==",
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.10.0.tgz",
+      "integrity": "sha512-yPtF9jIix88orwfTi0lJiqINnlWo6p93MtZEoaehZnmCzEmLL0eqjA3eGVeyQhMtxdV+Mlsgfwhh0+M/k1/V7Q==",
       "dev": true,
       "optional": true
     },
     "@rollup/rollup-linux-arm64-musl": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.9.6.tgz",
-      "integrity": "sha512-gpiG0qQJNdYEVad+1iAsGAbgAnZ8j07FapmnIAQgODKcOTjLEWM9sRb+MbQyVsYCnA0Im6M6QIq6ax7liws6eQ==",
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.10.0.tgz",
+      "integrity": "sha512-9GW9yA30ib+vfFiwjX+N7PnjTnCMiUffhWj4vkG4ukYv1kJ4T9gHNg8zw+ChsOccM27G9yXrEtMScf1LaCuoWQ==",
       "dev": true,
       "optional": true
     },
     "@rollup/rollup-linux-riscv64-gnu": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.9.6.tgz",
-      "integrity": "sha512-+uCOcvVmFUYvVDr27aiyun9WgZk0tXe7ThuzoUTAukZJOwS5MrGbmSlNOhx1j80GdpqbOty05XqSl5w4dQvcOA==",
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.10.0.tgz",
+      "integrity": "sha512-X1ES+V4bMq2ws5fF4zHornxebNxMXye0ZZjUrzOrf7UMx1d6wMQtfcchZ8SqUnQPPHdOyOLW6fTcUiFgHFadRA==",
       "dev": true,
       "optional": true
     },
     "@rollup/rollup-linux-x64-gnu": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.9.6.tgz",
-      "integrity": "sha512-HUNqM32dGzfBKuaDUBqFB7tP6VMN74eLZ33Q9Y1TBqRDn+qDonkAUyKWwF9BR9unV7QUzffLnz9GrnKvMqC/fw==",
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.10.0.tgz",
+      "integrity": "sha512-w/5OpT2EnI/Xvypw4FIhV34jmNqU5PZjZue2l2Y3ty1Ootm3SqhI+AmfhlUYGBTd9JnpneZCDnt3uNOiOBkMyw==",
       "dev": true,
       "optional": true
     },
     "@rollup/rollup-linux-x64-musl": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.9.6.tgz",
-      "integrity": "sha512-ch7M+9Tr5R4FK40FHQk8VnML0Szi2KRujUgHXd/HjuH9ifH72GUmw6lStZBo3c3GB82vHa0ZoUfjfcM7JiiMrQ==",
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.10.0.tgz",
+      "integrity": "sha512-q/meftEe3QlwQiGYxD9rWwB21DoKQ9Q8wA40of/of6yGHhZuGfZO0c3WYkN9dNlopHlNT3mf5BPsUSxoPuVQaw==",
       "dev": true,
       "optional": true
     },
     "@rollup/rollup-win32-arm64-msvc": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.9.6.tgz",
-      "integrity": "sha512-VD6qnR99dhmTQ1mJhIzXsRcTBvTjbfbGGwKAHcu+52cVl15AC/kplkhxzW/uT0Xl62Y/meBKDZvoJSJN+vTeGA==",
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.10.0.tgz",
+      "integrity": "sha512-NrR6667wlUfP0BHaEIKgYM/2va+Oj+RjZSASbBMnszM9k+1AmliRjHc3lJIiOehtSSjqYiO7R6KLNrWOX+YNSQ==",
       "dev": true,
       "optional": true
     },
     "@rollup/rollup-win32-ia32-msvc": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.9.6.tgz",
-      "integrity": "sha512-J9AFDq/xiRI58eR2NIDfyVmTYGyIZmRcvcAoJ48oDld/NTR8wyiPUu2X/v1navJ+N/FGg68LEbX3Ejd6l8B7MQ==",
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.10.0.tgz",
+      "integrity": "sha512-FV0Tpt84LPYDduIDcXvEC7HKtyXxdvhdAOvOeWMWbQNulxViH2O07QXkT/FffX4FqEI02jEbCJbr+YcuKdyyMg==",
       "dev": true,
       "optional": true
     },
     "@rollup/rollup-win32-x64-msvc": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.9.6.tgz",
-      "integrity": "sha512-jqzNLhNDvIZOrt69Ce4UjGRpXJBzhUBzawMwnaDAwyHriki3XollsewxWzOzz+4yOFDkuJHtTsZFwMxhYJWmLQ==",
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.10.0.tgz",
+      "integrity": "sha512-OZoJd+o5TaTSQeFFQ6WjFCiltiYVjIdsXxwu/XZ8qRpsvMQr4UsVrE5UyT9RIvsnuF47DqkJKhhVZ2Q9YW9IpQ==",
       "dev": true,
       "optional": true
     },
@@ -4273,9 +5664,9 @@
       "dev": true
     },
     "@types/trusted-types": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.3.tgz",
-      "integrity": "sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g=="
+      "version": "2.0.7",
+      "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
+      "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="
     },
     "@types/w3c-web-serial": {
       "version": "1.0.6",
@@ -4404,6 +5795,11 @@
       "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
       "dev": true
     },
+    "base64-js": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
+    },
     "blocking-elements": {
       "version": "0.1.1"
     },
@@ -4454,6 +5850,15 @@
         "update-browserslist-db": "^1.0.9"
       }
     },
+    "buffer": {
+      "version": "6.0.3",
+      "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
+      "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
+      "requires": {
+        "base64-js": "^1.3.1",
+        "ieee754": "^1.2.1"
+      }
+    },
     "buffer-from": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
@@ -4592,6 +5997,12 @@
       "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
       "dev": true
     },
+    "commondir": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
+      "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==",
+      "dev": true
+    },
     "compressible": {
       "version": "2.0.18",
       "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
@@ -4706,10 +6117,11 @@
       "dev": true
     },
     "esptool-js": {
-      "version": "0.3.2",
-      "resolved": "https://registry.npmjs.org/esptool-js/-/esptool-js-0.3.2.tgz",
-      "integrity": "sha512-hA58j6wxm143MTa1ZkM/uaDsaF2U+/2sdcoPVz5G78o7wENqzOb5KnHfhPGXK8mbhhYnmC7JXGhZ7wfgeB8DmQ==",
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/esptool-js/-/esptool-js-0.4.1.tgz",
+      "integrity": "sha512-JhPHyjBncwnZDmOWxzjCQV5e6m1qP9kXPsZy5Zn/cu4tBOfPL8McncIzNVCzmLn7Jvgi06Jg09OK2HrkyMSboA==",
       "requires": {
+        "buffer": "^6.0.3",
         "pako": "^2.1.0",
         "tslib": "^2.4.1"
       }
@@ -4752,6 +6164,12 @@
         "punycode": "^1.3.2"
       }
     },
+    "fs.realpath": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+      "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+      "dev": true
+    },
     "fsevents": {
       "version": "2.3.2",
       "dev": true,
@@ -4776,6 +6194,39 @@
       "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
       "dev": true
     },
+    "glob": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
+      "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
+      "dev": true,
+      "requires": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^5.0.1",
+        "once": "^1.3.0"
+      },
+      "dependencies": {
+        "brace-expansion": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+          "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+          "dev": true,
+          "requires": {
+            "balanced-match": "^1.0.0"
+          }
+        },
+        "minimatch": {
+          "version": "5.1.6",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
+          "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+          "dev": true,
+          "requires": {
+            "brace-expansion": "^2.0.1"
+          }
+        }
+      }
+    },
     "globals": {
       "version": "11.12.0",
       "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
@@ -4803,6 +6254,11 @@
       "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
       "dev": true
     },
+    "ieee754": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+      "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
+    },
     "improv-wifi-serial-sdk": {
       "version": "2.5.0",
       "resolved": "https://registry.npmjs.org/improv-wifi-serial-sdk/-/improv-wifi-serial-sdk-2.5.0.tgz",
@@ -4817,8 +6273,62 @@
         "@material/mwc-textfield": "^0.27.0",
         "lit": "^2.5.0",
         "tslib": "^2.4.1"
+      },
+      "dependencies": {
+        "@lit/reactive-element": {
+          "version": "1.6.3",
+          "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
+          "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.0.0"
+          }
+        },
+        "lit": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
+          "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+          "requires": {
+            "@lit/reactive-element": "^1.6.0",
+            "lit-element": "^3.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-element": {
+          "version": "3.3.3",
+          "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
+          "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
+          "requires": {
+            "@lit-labs/ssr-dom-shim": "^1.1.0",
+            "@lit/reactive-element": "^1.3.0",
+            "lit-html": "^2.8.0"
+          }
+        },
+        "lit-html": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+          "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+          "requires": {
+            "@types/trusted-types": "^2.0.2"
+          }
+        }
+      }
+    },
+    "inflight": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+      "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+      "dev": true,
+      "requires": {
+        "once": "^1.3.0",
+        "wrappy": "1"
       }
     },
+    "inherits": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+      "dev": true
+    },
     "ini": {
       "version": "1.3.8",
       "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
@@ -4865,6 +6375,15 @@
       "integrity": "sha512-9UoipoxYmSk6Xy7QFgRv2HDyaysmgSG75TFQs6S+3pDM7ZhKTF/bskZV+0UlABHzKjNVhPjYCLfeZUEg1wXxig==",
       "dev": true
     },
+    "is-reference": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz",
+      "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==",
+      "dev": true,
+      "requires": {
+        "@types/estree": "*"
+      }
+    },
     "is-stream": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
@@ -4912,29 +6431,29 @@
       "peer": true
     },
     "lit": {
-      "version": "2.8.0",
-      "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
-      "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/lit/-/lit-3.1.2.tgz",
+      "integrity": "sha512-VZx5iAyMtX7CV4K8iTLdCkMaYZ7ipjJZ0JcSdJ0zIdGxxyurjIn7yuuSxNBD7QmjvcNJwr0JS4cAdAtsy7gZ6w==",
       "requires": {
-        "@lit/reactive-element": "^1.6.0",
-        "lit-element": "^3.3.0",
-        "lit-html": "^2.8.0"
+        "@lit/reactive-element": "^2.0.4",
+        "lit-element": "^4.0.4",
+        "lit-html": "^3.1.2"
       }
     },
     "lit-element": {
-      "version": "3.3.2",
-      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.2.tgz",
-      "integrity": "sha512-xXAeVWKGr4/njq0rGC9dethMnYCq5hpKYrgQZYTzawt9YQhMiXfD+T1RgrdY3NamOxwq2aXlb0vOI6e29CKgVQ==",
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.0.4.tgz",
+      "integrity": "sha512-98CvgulX6eCPs6TyAIQoJZBCQPo80rgXR+dVBs61cstJXqtI+USQZAbA4gFHh6L/mxBx9MrgPLHLsUgDUHAcCQ==",
       "requires": {
-        "@lit-labs/ssr-dom-shim": "^1.1.0",
-        "@lit/reactive-element": "^1.3.0",
-        "lit-html": "^2.7.0"
+        "@lit-labs/ssr-dom-shim": "^1.2.0",
+        "@lit/reactive-element": "^2.0.4",
+        "lit-html": "^3.1.2"
       }
     },
     "lit-html": {
-      "version": "2.8.0",
-      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
-      "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.1.2.tgz",
+      "integrity": "sha512-3OBZSUrPnAHoKJ9AMjRL/m01YJxQMf+TMHanNtTHG68ubjnZxK0RFl102DPzsw4mWnHibfZIBJm3LWCZ/LmMvg==",
       "requires": {
         "@types/trusted-types": "^2.0.2"
       }
@@ -4949,6 +6468,15 @@
         "yallist": "^3.0.2"
       }
     },
+    "magic-string": {
+      "version": "0.30.7",
+      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.7.tgz",
+      "integrity": "sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==",
+      "dev": true,
+      "requires": {
+        "@jridgewell/sourcemap-codec": "^1.4.15"
+      }
+    },
     "merge-stream": {
       "version": "2.0.0",
       "dev": true
@@ -5031,6 +6559,15 @@
       "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
       "dev": true
     },
+    "once": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+      "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+      "dev": true,
+      "requires": {
+        "wrappy": "1"
+      }
+    },
     "onetime": {
       "version": "5.1.2",
       "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
@@ -5083,9 +6620,9 @@
       "dev": true
     },
     "prettier": {
-      "version": "3.2.4",
-      "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.4.tgz",
-      "integrity": "sha512-FWu1oLHKCrtpO1ypU6J0SbK2d9Ckwysq6bHj/uaCP26DxrPpppCLQRGVuqAxSTvhF00AcvDRyYrLNW7ocBhFFQ==",
+      "version": "3.2.5",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz",
+      "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==",
       "dev": true
     },
     "punycode": {
@@ -5158,24 +6695,24 @@
       }
     },
     "rollup": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.9.6.tgz",
-      "integrity": "sha512-05lzkCS2uASX0CiLFybYfVkwNbKZG5NFQ6Go0VWyogFTXXbR039UVsegViTntkk4OglHBdF54ccApXRRuXRbsg==",
-      "dev": true,
-      "requires": {
-        "@rollup/rollup-android-arm-eabi": "4.9.6",
-        "@rollup/rollup-android-arm64": "4.9.6",
-        "@rollup/rollup-darwin-arm64": "4.9.6",
-        "@rollup/rollup-darwin-x64": "4.9.6",
-        "@rollup/rollup-linux-arm-gnueabihf": "4.9.6",
-        "@rollup/rollup-linux-arm64-gnu": "4.9.6",
-        "@rollup/rollup-linux-arm64-musl": "4.9.6",
-        "@rollup/rollup-linux-riscv64-gnu": "4.9.6",
-        "@rollup/rollup-linux-x64-gnu": "4.9.6",
-        "@rollup/rollup-linux-x64-musl": "4.9.6",
-        "@rollup/rollup-win32-arm64-msvc": "4.9.6",
-        "@rollup/rollup-win32-ia32-msvc": "4.9.6",
-        "@rollup/rollup-win32-x64-msvc": "4.9.6",
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.10.0.tgz",
+      "integrity": "sha512-t2v9G2AKxcQ8yrG+WGxctBes1AomT0M4ND7jTFBCVPXQ/WFTvNSefIrNSmLKhIKBrvN8SG+CZslimJcT3W2u2g==",
+      "dev": true,
+      "requires": {
+        "@rollup/rollup-android-arm-eabi": "4.10.0",
+        "@rollup/rollup-android-arm64": "4.10.0",
+        "@rollup/rollup-darwin-arm64": "4.10.0",
+        "@rollup/rollup-darwin-x64": "4.10.0",
+        "@rollup/rollup-linux-arm-gnueabihf": "4.10.0",
+        "@rollup/rollup-linux-arm64-gnu": "4.10.0",
+        "@rollup/rollup-linux-arm64-musl": "4.10.0",
+        "@rollup/rollup-linux-riscv64-gnu": "4.10.0",
+        "@rollup/rollup-linux-x64-gnu": "4.10.0",
+        "@rollup/rollup-linux-x64-musl": "4.10.0",
+        "@rollup/rollup-win32-arm64-msvc": "4.10.0",
+        "@rollup/rollup-win32-ia32-msvc": "4.10.0",
+        "@rollup/rollup-win32-x64-msvc": "4.10.0",
         "@types/estree": "1.0.5",
         "fsevents": "~2.3.2"
       }
@@ -5452,6 +6989,12 @@
         }
       }
     },
+    "wrappy": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+      "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+      "dev": true
+    },
     "yallist": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
diff --git a/package.json b/package.json
index 98c9a5ef..37dd1b2b 100644
--- a/package.json
+++ b/package.json
@@ -12,28 +12,23 @@
   "devDependencies": {
     "@babel/plugin-proposal-class-properties": "^7.18.6",
     "@rollup/plugin-babel": "^6.0.4",
-    "@rollup/plugin-json": "^6.0.1",
+    "@rollup/plugin-commonjs": "^25.0.7",
+    "@rollup/plugin-json": "^6.1.0",
     "@rollup/plugin-node-resolve": "^15.2.3",
-    "@rollup/plugin-typescript": "^11.1.5",
     "@rollup/plugin-terser": "^0.4.4",
-    "@types/w3c-web-serial": "^1.0.3",
-    "prettier": "^3.0.0",
-    "rollup": "^4.3.0",
-    "serve": "^14.2.0",
-    "typescript": "^5.1.3"
+    "@rollup/plugin-typescript": "^11.1.6",
+    "@types/w3c-web-serial": "^1.0.6",
+    "prettier": "^3.2.5",
+    "rollup": "^4.10.0",
+    "serve": "^14.2.1",
+    "typescript": "^5.3.3"
   },
   "dependencies": {
-    "@material/mwc-button": "^0.27.0",
-    "@material/mwc-checkbox": "^0.27.0",
-    "@material/mwc-circular-progress": "^0.27.0",
-    "@material/mwc-dialog": "^0.27.0",
-    "@material/mwc-formfield": "^0.27.0",
-    "@material/mwc-icon-button": "^0.27.0",
-    "@material/mwc-textfield": "^0.27.0",
-    "esptool-js": "^0.3.2",
+    "@material/web": "^1.2.0",
+    "esptool-js": "^0.4.1",
     "improv-wifi-serial-sdk": "^2.5.0",
-    "lit": "^2.8.0",
+    "lit": "^3.1.2",
     "pako": "^2.1.0",
-    "tslib": "^2.5.3"
+    "tslib": "^2.6.2"
   }
 }
diff --git a/rollup.config.mjs b/rollup.config.mjs
index bdb67dd7..a7420332 100644
--- a/rollup.config.mjs
+++ b/rollup.config.mjs
@@ -2,6 +2,7 @@ import nodeResolve from "@rollup/plugin-node-resolve";
 import json from "@rollup/plugin-json";
 import terser from "@rollup/plugin-terser";
 import babel from "@rollup/plugin-babel";
+import commonjs from "@rollup/plugin-commonjs";
 
 const config = {
   input: "dist/install-button.js",
@@ -12,7 +13,11 @@ const config = {
   external: ["https://www.improv-wifi.com/sdk-js/launch-button.js"],
   preserveEntrySignatures: false,
   plugins: [
-    nodeResolve(),
+    commonjs(),
+    nodeResolve({
+      browser: true,
+      preferBuiltins: false,
+    }),
     babel({
       babelHelpers: "bundled",
       plugins: ["@babel/plugin-proposal-class-properties"],
diff --git a/src/components/ew-checkbox.ts b/src/components/ew-checkbox.ts
new file mode 100644
index 00000000..9509893d
--- /dev/null
+++ b/src/components/ew-checkbox.ts
@@ -0,0 +1,14 @@
+import { Checkbox } from "@material/web/checkbox/internal/checkbox.js";
+import { styles } from "@material/web/checkbox/internal/checkbox-styles.css.js";
+
+declare global {
+  interface HTMLElementTagNameMap {
+    "ew-checkbox": EwCheckbox;
+  }
+}
+
+export class EwCheckbox extends Checkbox {
+  static override styles = [styles];
+}
+
+customElements.define("ew-checkbox", EwCheckbox);
diff --git a/src/components/ew-circular-progress.ts b/src/components/ew-circular-progress.ts
new file mode 100644
index 00000000..b34c2e44
--- /dev/null
+++ b/src/components/ew-circular-progress.ts
@@ -0,0 +1,14 @@
+import { CircularProgress } from "@material/web/progress/internal/circular-progress.js";
+import { styles } from "@material/web/progress/internal/circular-progress-styles.css.js";
+
+declare global {
+  interface HTMLElementTagNameMap {
+    "ew-circular-progress": EwCircularProgress;
+  }
+}
+
+export class EwCircularProgress extends CircularProgress {
+  static override styles = [styles];
+}
+
+customElements.define("ew-circular-progress", EwCircularProgress);
diff --git a/src/components/ew-dialog.ts b/src/components/ew-dialog.ts
new file mode 100644
index 00000000..443c733d
--- /dev/null
+++ b/src/components/ew-dialog.ts
@@ -0,0 +1,14 @@
+import { Dialog } from "@material/web/dialog/internal/dialog.js";
+import { styles } from "@material/web/dialog/internal/dialog-styles.css";
+
+declare global {
+  interface HTMLElementTagNameMap {
+    "ew-dialog": EwDialog;
+  }
+}
+
+export class EwDialog extends Dialog {
+  static override styles = [styles];
+}
+
+customElements.define("ew-dialog", EwDialog);
diff --git a/src/components/ew-divider.ts b/src/components/ew-divider.ts
new file mode 100644
index 00000000..ed3f5e3f
--- /dev/null
+++ b/src/components/ew-divider.ts
@@ -0,0 +1,14 @@
+import { Divider } from "@material/web/divider/internal/divider.js";
+import { styles } from "@material/web/divider/internal/divider-styles.css.js";
+
+declare global {
+  interface HTMLElementTagNameMap {
+    "ew-divider": EwDivider;
+  }
+}
+
+export class EwDivider extends Divider {
+  static override styles = [styles];
+}
+
+customElements.define("ew-divider", EwDivider);
diff --git a/src/components/ew-filled-select.ts b/src/components/ew-filled-select.ts
new file mode 100644
index 00000000..fac5b752
--- /dev/null
+++ b/src/components/ew-filled-select.ts
@@ -0,0 +1,15 @@
+import { FilledSelect } from "@material/web/select/internal/filled-select.js";
+import { styles } from "@material/web/select/internal/filled-select-styles.css.js";
+import { styles as sharedStyles } from "@material/web/select/internal/shared-styles.css.js";
+
+declare global {
+  interface HTMLElementTagNameMap {
+    "ew-filled-select": EwFilledSelect;
+  }
+}
+
+export class EwFilledSelect extends FilledSelect {
+  static override styles = [sharedStyles, styles];
+}
+
+customElements.define("ew-filled-select", EwFilledSelect);
diff --git a/src/components/ew-filled-text-field.ts b/src/components/ew-filled-text-field.ts
new file mode 100644
index 00000000..70d379ff
--- /dev/null
+++ b/src/components/ew-filled-text-field.ts
@@ -0,0 +1,17 @@
+import { styles as filledStyles } from "@material/web/textfield/internal/filled-styles.css.js";
+import { FilledTextField } from "@material/web/textfield/internal/filled-text-field.js";
+import { styles as sharedStyles } from "@material/web/textfield/internal/shared-styles.css.js";
+import { literal } from "lit/static-html.js";
+
+declare global {
+  interface HTMLElementTagNameMap {
+    "ew-filled-text-field": EwFilledTextField;
+  }
+}
+
+export class EwFilledTextField extends FilledTextField {
+  static override styles = [sharedStyles, filledStyles];
+  protected override readonly fieldTag = literal`md-filled-field`;
+}
+
+customElements.define("ew-filled-text-field", EwFilledTextField);
diff --git a/src/components/ew-icon-button.ts b/src/components/ew-icon-button.ts
new file mode 100644
index 00000000..a873152b
--- /dev/null
+++ b/src/components/ew-icon-button.ts
@@ -0,0 +1,15 @@
+import { IconButton } from "@material/web/iconbutton/internal/icon-button.js";
+import { styles as sharedStyles } from "@material/web/iconbutton/internal/shared-styles.css.js";
+import { styles } from "@material/web/iconbutton/internal/standard-styles.css.js";
+
+declare global {
+  interface HTMLElementTagNameMap {
+    "ew-icon-button": EwIconButton;
+  }
+}
+
+export class EwIconButton extends IconButton {
+  static override styles = [sharedStyles, styles];
+}
+
+customElements.define("ew-icon-button", EwIconButton);
diff --git a/src/components/ew-list-item.ts b/src/components/ew-list-item.ts
new file mode 100644
index 00000000..6fd5336f
--- /dev/null
+++ b/src/components/ew-list-item.ts
@@ -0,0 +1,14 @@
+import { ListItemEl as ListItem } from "@material/web/list/internal/listitem/list-item.js";
+import { styles } from "@material/web/list/internal/listitem/list-item-styles.css.js";
+
+declare global {
+  interface HTMLElementTagNameMap {
+    "ew-list-item": EwListItem;
+  }
+}
+
+export class EwListItem extends ListItem {
+  static override styles = [styles];
+}
+
+customElements.define("ew-list-item", EwListItem);
diff --git a/src/components/ew-list.ts b/src/components/ew-list.ts
new file mode 100644
index 00000000..77fbc746
--- /dev/null
+++ b/src/components/ew-list.ts
@@ -0,0 +1,14 @@
+import { List } from "@material/web/list/internal/list.js";
+import { styles } from "@material/web/list/internal/list-styles.css.js";
+
+declare global {
+  interface HTMLElementTagNameMap {
+    "ew-list": EwList;
+  }
+}
+
+export class EwList extends List {
+  static override styles = [styles];
+}
+
+customElements.define("ew-list", EwList);
diff --git a/src/components/ew-select-option.ts b/src/components/ew-select-option.ts
new file mode 100644
index 00000000..64abec61
--- /dev/null
+++ b/src/components/ew-select-option.ts
@@ -0,0 +1,14 @@
+import { styles } from "@material/web/menu/internal/menuitem/menu-item-styles.css.js";
+import { SelectOptionEl } from "@material/web/select/internal/selectoption/select-option.js";
+
+declare global {
+  interface HTMLElementTagNameMap {
+    "ew-select-option": EwSelectOption;
+  }
+}
+
+export class EwSelectOption extends SelectOptionEl {
+  static override styles = [styles];
+}
+
+customElements.define("ew-select-option", EwSelectOption);
diff --git a/src/components/ew-text-button.ts b/src/components/ew-text-button.ts
new file mode 100644
index 00000000..bf025bf8
--- /dev/null
+++ b/src/components/ew-text-button.ts
@@ -0,0 +1,15 @@
+import { styles as sharedStyles } from "@material/web/button/internal/shared-styles.css.js";
+import { TextButton } from "@material/web/button/internal/text-button.js";
+import { styles as textStyles } from "@material/web/button/internal/text-styles.css.js";
+
+declare global {
+  interface HTMLElementTagNameMap {
+    "ew-text-button": EwTextButton;
+  }
+}
+
+export class EwTextButton extends TextButton {
+  static override styles = [sharedStyles, textStyles];
+}
+
+customElements.define("ew-text-button", EwTextButton);
diff --git a/src/components/ewt-button.ts b/src/components/ewt-button.ts
deleted file mode 100644
index 046fe5c2..00000000
--- a/src/components/ewt-button.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { css } from "lit";
-import { ButtonBase } from "@material/mwc-button/mwc-button-base";
-import { styles } from "@material/mwc-button/styles.css";
-
-declare global {
-  interface HTMLElementTagNameMap {
-    "ewt-button": EwtButton;
-  }
-}
-
-export class EwtButton extends ButtonBase {
-  static override styles = [
-    styles,
-    css`
-      .mdc-button {
-        min-width: initial;
-      }
-      :host([text-left]) .mdc-button__label {
-        text-align: left;
-      }
-    `,
-  ];
-}
-
-customElements.define("ewt-button", EwtButton);
diff --git a/src/components/ewt-checkbox.ts b/src/components/ewt-checkbox.ts
deleted file mode 100644
index 901ee03d..00000000
--- a/src/components/ewt-checkbox.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { CheckboxBase } from "@material/mwc-checkbox/mwc-checkbox-base";
-import { styles } from "@material/mwc-checkbox/mwc-checkbox.css";
-
-declare global {
-  interface HTMLElementTagNameMap {
-    "ewt-checkbox": EwtCheckbox;
-  }
-}
-
-export class EwtCheckbox extends CheckboxBase {
-  static override styles = [styles];
-}
-
-customElements.define("ewt-checkbox", EwtCheckbox);
diff --git a/src/components/ewt-circular-progress.ts b/src/components/ewt-circular-progress.ts
deleted file mode 100644
index 13c7d7b9..00000000
--- a/src/components/ewt-circular-progress.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { CircularProgressBase } from "@material/mwc-circular-progress/mwc-circular-progress-base";
-import { styles } from "@material/mwc-circular-progress/mwc-circular-progress.css";
-
-declare global {
-  interface HTMLElementTagNameMap {
-    "ewt-circular-progress": EwtCircularProgress;
-  }
-}
-
-export class EwtCircularProgress extends CircularProgressBase {
-  static override styles = [styles];
-}
-
-customElements.define("ewt-circular-progress", EwtCircularProgress);
diff --git a/src/components/ewt-formfield.ts b/src/components/ewt-formfield.ts
deleted file mode 100644
index 8fafb41b..00000000
--- a/src/components/ewt-formfield.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { FormfieldBase } from "@material/mwc-formfield/mwc-formfield-base";
-import { styles } from "@material/mwc-formfield/mwc-formfield.css";
-
-declare global {
-  interface HTMLElementTagNameMap {
-    "ewt-formfield": EwtFormfield;
-  }
-}
-
-export class EwtFormfield extends FormfieldBase {
-  static override styles = [styles];
-}
-
-customElements.define("ewt-formfield", EwtFormfield);
diff --git a/src/components/ewt-icon-button.ts b/src/components/ewt-icon-button.ts
deleted file mode 100644
index b50be76d..00000000
--- a/src/components/ewt-icon-button.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { IconButtonBase } from "@material/mwc-icon-button/mwc-icon-button-base";
-import { styles } from "@material/mwc-icon-button/mwc-icon-button.css";
-
-declare global {
-  interface HTMLElementTagNameMap {
-    "ewt-icon-button": EwtIconButton;
-  }
-}
-
-export class EwtIconButton extends IconButtonBase {
-  static override styles = [styles];
-}
-
-customElements.define("ewt-icon-button", EwtIconButton);
diff --git a/src/components/ewt-list-item.ts b/src/components/ewt-list-item.ts
deleted file mode 100644
index 6494d8e9..00000000
--- a/src/components/ewt-list-item.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { ListItemBase } from "@material/mwc-list/mwc-list-item-base";
-import { styles } from "@material/mwc-list/mwc-list-item.css";
-
-declare global {
-  interface HTMLElementTagNameMap {
-    "ewt-list-item": EwtListItem;
-  }
-}
-
-export class EwtListItem extends ListItemBase {
-  static override styles = [styles];
-}
-
-customElements.define("ewt-list-item", EwtListItem);
diff --git a/src/components/ewt-select.ts b/src/components/ewt-select.ts
deleted file mode 100644
index 6f390f18..00000000
--- a/src/components/ewt-select.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import { SelectBase } from "@material/mwc-select/mwc-select-base";
-import { styles } from "@material/mwc-select/mwc-select.css";
-import { css } from "lit";
-
-declare global {
-  interface HTMLElementTagNameMap {
-    "ewt-select": EwtSelect;
-  }
-}
-
-export class EwtSelect extends SelectBase {
-  static override styles = [
-    styles,
-    // rem -> em conversion
-    css`
-      .mdc-floating-label {
-        line-height: 1.15em;
-      }
-    `,
-  ];
-}
-
-customElements.define("ewt-select", EwtSelect);
diff --git a/src/components/ewt-textfield.ts b/src/components/ewt-textfield.ts
deleted file mode 100644
index 6ecc319b..00000000
--- a/src/components/ewt-textfield.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import { TextFieldBase } from "@material/mwc-textfield/mwc-textfield-base";
-import { styles } from "@material/mwc-textfield/mwc-textfield.css";
-import { css } from "lit";
-
-declare global {
-  interface HTMLElementTagNameMap {
-    "ewt-textfield": EwtTextfield;
-  }
-}
-
-export class EwtTextfield extends TextFieldBase {
-  static override styles = [
-    styles,
-    // rem -> em conversion
-    css`
-      .mdc-floating-label {
-        line-height: 1.15em;
-      }
-    `,
-  ];
-}
-
-customElements.define("ewt-textfield", EwtTextfield);
diff --git a/src/components/svg.ts b/src/components/svg.ts
index e7f23674..d96280fc 100644
--- a/src/components/svg.ts
+++ b/src/components/svg.ts
@@ -3,34 +3,59 @@ import { svg } from "lit";
 export const closeIcon = svg`
   
     
   
 `;
 
-export const firmwareIcon = svg`
-  
+export const refreshIcon = svg`
+  
     
   
 `;
 
-export const chipIcon = svg`
-  
-    
+export const listItemInstallIcon = svg`
+  
+    
   
 `;
 
-export const refreshIcon = svg`
-  
-    
+export const listItemWifi = svg`
+  
+    
+  
+`;
+
+export const listItemConsole = svg`
+  
+    
+  
+`;
+
+export const listItemVisitDevice = svg`
+  
+  
+  
+`;
+
+export const listItemHomeAssistant = svg`
+  
+    
+  
+`;
+
+export const listItemEraseUserData = svg`
+  
+    
+  
+`;
+
+export const listItemFundDevelopment = svg`
+  
+    
   
 `;
diff --git a/src/const.ts b/src/const.ts
index 5dbd87f3..07498025 100644
--- a/src/const.ts
+++ b/src/const.ts
@@ -5,7 +5,15 @@ export interface Logger {
 }
 
 export interface Build {
-  chipFamily: "ESP32" | "ESP8266" | "ESP32-S2" | "ESP32-S3" | "ESP32-C3";
+  chipFamily:
+    | "ESP32"
+    | "ESP32-C2"
+    | "ESP32-C3"
+    | "ESP32-C6"
+    | "ESP32-H2"
+    | "ESP32-S2"
+    | "ESP32-S3"
+    | "ESP8266";
   parts: {
     path: string;
     offset: number;
diff --git a/src/flash.ts b/src/flash.ts
index cb20440c..25c228e2 100644
--- a/src/flash.ts
+++ b/src/flash.ts
@@ -44,6 +44,7 @@ export const flash = async (
     transport,
     baudrate: 115200,
     romBaudrate: 115200,
+    enableTracing: false,
   });
 
   // For debugging
@@ -56,8 +57,8 @@ export const flash = async (
   });
 
   try {
-    await esploader.main_fn();
-    await esploader.flash_id();
+    await esploader.main();
+    await esploader.flashId();
   } catch (err: any) {
     console.error(err);
     fireStateEvent({
@@ -166,7 +167,7 @@ export const flash = async (
       message: "Erasing device...",
       details: { done: false },
     });
-    await esploader.erase_flash();
+    await esploader.eraseFlash();
     fireStateEvent({
       state: FlashStateType.ERASING,
       message: "Device erased",
@@ -187,7 +188,7 @@ export const flash = async (
   let totalWritten = 0;
 
   try {
-    await esploader.write_flash({
+    await esploader.writeFlash({
       fileArray,
       flashSize: "keep",
       flashMode: "keep",
diff --git a/src/install-button.ts b/src/install-button.ts
index 873aeda4..fbe632ab 100644
--- a/src/install-button.ts
+++ b/src/install-button.ts
@@ -12,12 +12,12 @@ export class InstallButton extends HTMLElement {
     position: relative;
     cursor: pointer;
     font-size: 14px;
-    padding: 8px 28px;
+    font-weight: 500;
+    padding: 10px 24px;
     color: var(--esp-tools-button-text-color, #fff);
     background-color: var(--esp-tools-button-color, #03a9f4);
     border: none;
-    border-radius: 4px;
-    box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.12), 0 1px 5px 0 rgba(0,0,0,.2);
+    border-radius: var(--esp-tools-button-border-radius, 9999px);
   }
   button::before {
     content: " ";
@@ -27,10 +27,7 @@ export class InstallButton extends HTMLElement {
     left: 0;
     right: 0;
     opacity: 0.2;
-    border-radius: 4px;
-  }
-  button:hover {
-    box-shadow: 0 4px 8px 0 rgba(0,0,0,.14), 0 1px 7px 0 rgba(0,0,0,.12), 0 3px 1px -1px rgba(0,0,0,.2);
+    border-radius: var(--esp-tools-button-border-radius, 9999px);
   }
   button:hover::before {
     background-color: rgba(255,255,255,.8);
@@ -51,10 +48,6 @@ export class InstallButton extends HTMLElement {
     cursor: unset;
     pointer-events: none;
   }
-  improv-wifi-launch-button {
-    display: block;
-    margin-top: 16px;
-  }
   .hidden {
     display: none;
   }`;
@@ -101,7 +94,7 @@ export class InstallButton extends HTMLElement {
 
     slot.name = "activate";
     const button = document.createElement("button");
-    button.innerText = "CONNECT";
+    button.innerText = "Connect";
     slot.append(button);
     if (
       "adoptedStyleSheets" in Document.prototype &&
diff --git a/src/install-dialog.ts b/src/install-dialog.ts
index 85a49a83..d1aadb60 100644
--- a/src/install-dialog.ts
+++ b/src/install-dialog.ts
@@ -1,21 +1,26 @@
 import { LitElement, html, PropertyValues, css, TemplateResult } from "lit";
 import { state } from "lit/decorators.js";
-import "./components/ewt-button";
-import "./components/ewt-checkbox";
+import "./components/ew-text-button";
+import "./components/ew-list";
+import "./components/ew-list-item";
+import "./components/ew-divider";
+import "./components/ew-checkbox";
 import "./components/ewt-console";
-import "./components/ewt-dialog";
-import "./components/ewt-formfield";
-import "./components/ewt-icon-button";
-import "./components/ewt-textfield";
-import type { EwtTextfield } from "./components/ewt-textfield";
-import "./components/ewt-select";
-import "./components/ewt-list-item";
+import "./components/ew-dialog";
+import "./components/ew-icon-button";
+import "./components/ew-filled-text-field";
+import type { EwFilledTextField } from "./components/ew-filled-text-field";
+import "./components/ew-filled-select";
+import "./components/ew-select-option";
 import "./pages/ewt-page-progress";
 import "./pages/ewt-page-message";
 import {
-  chipIcon,
   closeIcon,
-  firmwareIcon,
+  listItemConsole,
+  listItemHomeAssistant,
+  listItemInstallIcon,
+  listItemVisitDevice,
+  listItemWifi,
   refreshIcon,
 } from "./components/svg";
 import { Logger, Manifest, FlashStateType, FlashState } from "./const.js";
@@ -32,6 +37,7 @@ import { sleep } from "./util/sleep";
 import { downloadManifest } from "./util/manifest";
 import { dialogStyles } from "./styles";
 import { version } from "./version";
+import type { EwFilledSelect } from "./components/ew-filled-select";
 
 console.log(
   `ESP Web Tools ${version} by Nabu Casa; https://esphome.github.io/esp-web-tools/`,
@@ -87,13 +93,14 @@ export class EwtInstallDialog extends LitElement {
   // Name of Ssid. Null = other
   @state() private _selectedSsid: string | null = null;
 
+  private _bodyOverflow: string | null = null;
+
   protected render() {
     if (!this.port) {
       return html``;
     }
     let heading: string | undefined;
     let content: TemplateResult;
-    let hideActions = false;
     let allowClosing = false;
 
     // During installation phase we temporarily remove the client
@@ -103,94 +110,90 @@ export class EwtInstallDialog extends LitElement {
       this._state !== "LOGS"
     ) {
       if (this._error) {
-        [heading, content, hideActions] = this._renderError(this._error);
+        [heading, content] = this._renderError(this._error);
       } else {
         content = this._renderProgress("Connecting");
-        hideActions = true;
       }
     } else if (this._state === "INSTALL") {
-      [heading, content, hideActions, allowClosing] = this._renderInstall();
+      [heading, content, allowClosing] = this._renderInstall();
     } else if (this._state === "ASK_ERASE") {
       [heading, content] = this._renderAskErase();
     } else if (this._state === "ERROR") {
-      [heading, content, hideActions] = this._renderError(this._error!);
+      [heading, content] = this._renderError(this._error!);
     } else if (this._state === "DASHBOARD") {
-      [heading, content, hideActions, allowClosing] = this._client
+      [heading, content, allowClosing] = this._client
         ? this._renderDashboard()
         : this._renderDashboardNoImprov();
     } else if (this._state === "PROVISION") {
-      [heading, content, hideActions] = this._renderProvision();
+      [heading, content] = this._renderProvision();
     } else if (this._state === "LOGS") {
-      [heading, content, hideActions] = this._renderLogs();
+      [heading, content] = this._renderLogs();
     }
 
     return html`
-      
-        ${heading && allowClosing
+        ${heading ? html`
${heading}
` : ""} + ${allowClosing ? html` - + ${closeIcon} - + ` : ""} ${content!} - + `; } _renderProgress(label: string | TemplateResult, progress?: number) { return html` `; } - _renderError(label: string): [string, TemplateResult, boolean] { + _renderError(label: string): [string, TemplateResult] { const heading = "Error"; const content = html` - - + +
+ Close +
`; - const hideActions = false; - return [heading, content, hideActions]; + return [heading, content]; } - _renderDashboard(): [string, TemplateResult, boolean, boolean] { - const heading = this._info!.name; + _renderDashboard(): [string, TemplateResult, boolean] { + const heading = this._manifest.name; let content: TemplateResult; - let hideActions = true; let allowClosing = true; content = html` -
- ${firmwareIcon} -
${this._info!.firmware} ${this._info!.version}
-
-
- ${chipIcon} -
${this._info!.chipFamily}
-
-
- ${!this._isSameVersion - ? html` -
- + + +
Connected to ${this._info!.name}
+
+ ${this._info!.firmware} ${this._info!.version} + (${this._info!.chipFamily}) +
+
+ ${!this._isSameVersion + ? html` + { if (this._isSameFirmware) { this._startInstall(false); @@ -200,42 +203,43 @@ export class EwtInstallDialog extends LitElement { this._startInstall(true); } }} - >
-
- ` - : ""} - ${this._client!.nextUrl === undefined - ? "" - : html` - - `} - ${!this._manifest.home_assistant_domain || - this._client!.state !== ImprovSerialCurrentState.PROVISIONED - ? "" - : html` - + + `} + ${!this._manifest.home_assistant_domain || + this._client!.state !== ImprovSerialCurrentState.PROVISIONED + ? "" + : html` + - - -
- `} -
- Add to Home Assistant
+ + `} + { this._state = "PROVISION"; if ( @@ -244,11 +248,16 @@ export class EwtInstallDialog extends LitElement { this._provisionForce = true; } }} - > - -
- + ${listItemWifi} +
+ ${this._client!.state === ImprovSerialCurrentState.READY + ? "Connect to Wi-Fi" + : "Change Wi-Fi"} +
+ + { const client = this._client; if (client) { @@ -259,49 +268,48 @@ export class EwtInstallDialog extends LitElement { this._client = undefined; this._state = "LOGS"; }} - >
-
- ${this._isSameFirmware && this._manifest.funding_url - ? html` - - ` - : ""} - ${this._isSameVersion - ? html` -
- Fund Development
+
+ ` + : ""} + ${this._isSameVersion + ? html` + this._startInstall(true)} - > - - ` - : ""} + > +
Erase User Data
+
+ ` + : ""} + `; - return [heading, content, hideActions, allowClosing]; + return [heading, content, allowClosing]; } - _renderDashboardNoImprov(): [string, TemplateResult, boolean, boolean] { - const heading = "Device Dashboard"; + _renderDashboardNoImprov(): [string, TemplateResult, boolean] { + const heading = this._manifest.name; let content: TemplateResult; - let hideActions = true; let allowClosing = true; content = html` -
-
- + + { if (this._manifest.new_install_prompt_erase) { this._state = "ASK_ERASE"; @@ -310,29 +318,31 @@ export class EwtInstallDialog extends LitElement { this._startInstall(true); } }} - > -
- -
- + ${listItemInstallIcon} +
${`Install ${this._manifest.name}`}
+ + { // Also set `null` back to undefined. this._client = undefined; this._state = "LOGS"; }} - >
-
+ > + ${listItemConsole} +
Logs & Console
+ +
`; - return [heading, content, hideActions, allowClosing]; + return [heading, content, allowClosing]; } - _renderProvision(): [string | undefined, TemplateResult, boolean] { + _renderProvision(): [string | undefined, TemplateResult] { let heading: string | undefined = "Configure Wi-Fi"; let content: TemplateResult; - let hideActions = false; if (this._busy) { return [ @@ -342,7 +352,6 @@ export class EwtInstallDialog extends LitElement { ? "Scanning for networks" : "Trying to connect", ), - true, ]; } @@ -355,68 +364,72 @@ export class EwtInstallDialog extends LitElement { !this._wasProvisioned && (this._client!.nextUrl !== undefined || "home_assistant_domain" in this._manifest); - hideActions = showSetupLinks; content = html` - - ${showSetupLinks - ? html` - - `} -
- Add to Home Assistant
+ + `} + { this._state = "DASHBOARD"; }} - > - + > +
+
Skip
+
+ + ` + : ""} + + + ${!showSetupLinks + ? html` +
+ { + this._state = "DASHBOARD"; + }} + > + Continue +
` - : html` - { - this._state = "DASHBOARD"; - }} - > - `} + : ""} `; } else { let error: string | undefined; @@ -442,113 +455,117 @@ export class EwtInstallDialog extends LitElement { (info) => info.name === this._selectedSsid, ); content = html` -
- Enter the credentials of the Wi-Fi network that you want your device - to connect to. -
- ${error ? html`

${error}

` : ""} - ${this._ssids !== null - ? html` - { - const index = ev.detail.index; - // The "Join Other" item is always the last item. - this._selectedSsid = - index === this._ssids!.length - ? null - : this._ssids![index].name; - }} - @closed=${(ev: Event) => ev.stopPropagation()} - > - ${this._ssids!.map( - (info) => html` - - ${info.name} - - `, - )} - - Join other… - - - - ${refreshIcon} - - ` - : ""} - ${ - // Show input box if command not supported or "Join Other" selected - !selectedSsid + + ${refreshIcon} + +
+
Connect your device to the network to start using it.
+ ${error ? html`

${error}

` : ""} + ${this._ssids !== null ? html` - + { + const index = ev.target.selectedIndex; + // The "Join Other" item is always the last item. + this._selectedSsid = + index === this._ssids!.length + ? null + : this._ssids![index].name; + }} + > + ${this._ssids!.map( + (info) => html` + + ${info.name} + + `, + )} + + + Join other… + + ` - : "" - } - ${!selectedSsid || selectedSsid.secured - ? html` - - ` - : ""} - - { - this._state = "DASHBOARD"; - }} - > + : ""} + ${ + // Show input box if command not supported or "Join Other" selected + !selectedSsid + ? html` + + ` + : "" + } + ${!selectedSsid || selectedSsid.secured + ? html` + + ` + : ""} +
+
+ { + this._state = "DASHBOARD"; + }} + > + ${this._installState && this._installErase ? "Skip" : "Back"} + + Connect +
`; } - return [heading, content, hideActions]; + return [heading, content]; } _renderAskErase(): [string | undefined, TemplateResult] { const heading = "Erase device"; const content = html` -
- Do you want to erase the device before installing - ${this._manifest.name}? All data on the device will be lost. +
+
+ Do you want to erase the device before installing + ${this._manifest.name}? All data on the device will be lost. +
+ +
+
+ { + this._state = "DASHBOARD"; + }} + > + Back + + { + const checkbox = this.shadowRoot!.querySelector("ew-checkbox")!; + this._startInstall(checkbox.checked); + }} + > + Next +
- - - - { - const checkbox = this.shadowRoot!.querySelector("ewt-checkbox")!; - this._startInstall(checkbox.checked); - }} - > - { - this._state = "DASHBOARD"; - }} - > `; return [heading, content]; } - _renderInstall(): [string | undefined, TemplateResult, boolean, boolean] { + _renderInstall(): [string | undefined, TemplateResult, boolean] { let heading: string | undefined; let content: TemplateResult; - let hideActions = false; const allowClosing = false; const isUpdate = !this._installErase && this._isSameFirmware; @@ -556,40 +573,43 @@ export class EwtInstallDialog extends LitElement { if (!this._installConfirmed && this._isSameVersion) { heading = "Erase User Data"; content = html` - Do you want to reset your device and erase all user data from your - device? - +
+ Do you want to reset your device and erase all user data from your + device? +
+
+ + Erase User Data + +
`; } else if (!this._installConfirmed) { heading = "Confirm Installation"; const action = isUpdate ? "update to" : "install"; content = html` - ${isUpdate - ? html`Your device is running - ${this._info!.firmware} ${this._info!.version}.

` - : ""} - Do you want to ${action} - ${this._manifest.name} ${this._manifest.version}? - ${this._installErase - ? html`

All data on the device will be erased.` - : ""} - - { - this._state = "DASHBOARD"; - }} - > +
+ ${isUpdate + ? html`Your device is running + ${this._info!.firmware} ${this._info!.version}.

` + : ""} + Do you want to ${action} + ${this._manifest.name} ${this._manifest.version}? + ${this._installErase + ? html`

All data on the device will be erased.` + : ""} +
+
+ { + this._state = "DASHBOARD"; + }} + > + Back + + + Install + +
`; } else if ( !this._installState || @@ -598,11 +618,9 @@ export class EwtInstallDialog extends LitElement { ) { heading = "Installing"; content = this._renderProgress("Preparing installation"); - hideActions = true; } else if (this._installState.state === FlashStateType.ERASING) { heading = "Installing"; content = this._renderProgress("Erasing"); - hideActions = true; } else if ( this._installState.state === FlashStateType.WRITING || // When we're finished, keep showing this screen with 100% written @@ -635,82 +653,93 @@ export class EwtInstallDialog extends LitElement { `, percentage, ); - hideActions = true; } else if (this._installState.state === FlashStateType.FINISHED) { heading = undefined; const supportsImprov = this._client !== null; content = html` - { - this._state = - supportsImprov && this._installErase ? "PROVISION" : "DASHBOARD"; - }} - > + +
+ { + this._state = + supportsImprov && this._installErase + ? "PROVISION" + : "DASHBOARD"; + }} + > + Next + +
`; } else if (this._installState.state === FlashStateType.ERROR) { heading = "Installation failed"; content = html` - { - this._initialize(); - this._state = "DASHBOARD"; - }} - > +
+ { + this._initialize(); + this._state = "DASHBOARD"; + }} + > + Back + +
`; } - return [heading, content!, hideActions, allowClosing]; + return [heading, content!, allowClosing]; } - _renderLogs(): [string | undefined, TemplateResult, boolean] { + _renderLogs(): [string | undefined, TemplateResult] { let heading: string | undefined = `Logs`; let content: TemplateResult; - let hideActions = false; content = html` - - { - await this.shadowRoot!.querySelector("ewt-console")!.disconnect(); - this._state = "DASHBOARD"; - this._initialize(); - }} - > - { - textDownload( - this.shadowRoot!.querySelector("ewt-console")!.logs(), - `esp-web-tools-logs.txt`, - ); - - this.shadowRoot!.querySelector("ewt-console")!.reset(); - }} - > - { - await this.shadowRoot!.querySelector("ewt-console")!.reset(); - }} - > +
+ +
+
+ { + await this.shadowRoot!.querySelector("ewt-console")!.reset(); + }} + > + Reset Device + + { + textDownload( + this.shadowRoot!.querySelector("ewt-console")!.logs(), + `esp-web-tools-logs.txt`, + ); + + this.shadowRoot!.querySelector("ewt-console")!.reset(); + }} + > + Download Logs + + { + await this.shadowRoot!.querySelector("ewt-console")!.disconnect(); + this._state = "DASHBOARD"; + this._initialize(); + }} + > + Back + +
`; - return [heading, content!, hideActions]; + return [heading, content!]; } public override willUpdate(changedProps: PropertyValues) { @@ -780,6 +809,8 @@ export class EwtInstallDialog extends LitElement { protected override firstUpdated(changedProps: PropertyValues) { super.firstUpdated(changedProps); + this._bodyOverflow = document.body.style.overflow; + document.body.style.overflow = "hidden"; this._initialize(); } @@ -796,14 +827,16 @@ export class EwtInstallDialog extends LitElement { if (changedProps.has("_selectedSsid") && this._selectedSsid === null) { // If we pick "Join other", select SSID input. - this._focusFormElement("ewt-textfield[name=ssid]"); + this._focusFormElement("ew-filled-text-field[name=ssid]"); } else if (changedProps.has("_ssids")) { // Form is shown when SSIDs are loaded/marked not supported this._focusFormElement(); } } - private _focusFormElement(selector = "ewt-textfield, ewt-select") { + private _focusFormElement( + selector = "ew-filled-text-field, ew-filled-select", + ) { const formEl = this.shadowRoot!.querySelector( selector, ) as LitElement | null; @@ -900,7 +933,6 @@ export class EwtInstallDialog extends LitElement { this._manifest, this._installErase, ); - // YOLO2 } private async _doProvision() { @@ -911,15 +943,15 @@ export class EwtInstallDialog extends LitElement { this._selectedSsid === null ? ( this.shadowRoot!.querySelector( - "ewt-textfield[name=ssid]", - ) as EwtTextfield + "ew-filled-text-field[name=ssid]", + ) as EwFilledTextField ).value : this._selectedSsid; const password = ( this.shadowRoot!.querySelector( - "ewt-textfield[name=password]", - ) as EwtTextfield | null + "ew-filled-text-field[name=password]", + ) as EwFilledTextField | null )?.value || ""; try { await this._client!.provision(ssid, password, 30000); @@ -936,11 +968,16 @@ export class EwtInstallDialog extends LitElement { this._error = "Disconnected"; }; + private _closeDialog() { + this.shadowRoot!.querySelector("ew-dialog")!.close(); + } + private async _handleClose() { if (this._client) { await this._closeClientWithoutEvents(this._client); } fireEvent(this, "closed" as any); + document.body.style.overflow = this._bodyOverflow!; this.parentNode!.removeChild(this); } @@ -969,16 +1006,30 @@ export class EwtInstallDialog extends LitElement { await client.close(); } + private _preventDefault(ev: Event) { + ev.preventDefault(); + } + static styles = [ dialogStyles, css` :host { --mdc-dialog-max-width: 390px; } - ewt-icon-button { + div[slot="headline"] { + padding-right: 48px; + } + ew-icon-button[slot="headline"] { position: absolute; right: 4px; - top: 10px; + top: 8px; + } + ew-icon-button[slot="headline"] svg { + padding: 8px; + color: var(--text-color); + } + .dialog-nav svg { + color: var(--text-color); } .table-row { display: flex; @@ -990,27 +1041,37 @@ export class EwtInstallDialog extends LitElement { width: 20px; margin-right: 8px; } - ewt-textfield, - ewt-select { + ew-filled-text-field, + ew-filled-select { display: block; margin-top: 16px; } - .dashboard-buttons { - margin: 0 0 -16px -8px; + label.formfield { + display: inline-flex; + align-items: center; + padding-right: 8px; } - .dashboard-buttons div { - display: block; - margin: 4px 0; + ew-list { + margin: 0 -24px; + padding: 0; } - a.has-button { - text-decoration: none; + ew-list-item svg { + height: 24px; + } + ewt-page-message + ew-list { + padding-top: 16px; + } + .fake-icon { + width: 24px; } .error { - color: var(--improv-danger-color); + color: var(--danger-color); } .danger { - --mdc-theme-primary: var(--improv-danger-color); - --mdc-theme-secondary: var(--improv-danger-color); + --mdc-theme-primary: var(--danger-color); + --mdc-theme-secondary: var(--danger-color); + --md-sys-color-primary: var(--danger-color); + --md-sys-color-on-surface: var(--danger-color); } button.link { background: none; @@ -1022,15 +1083,13 @@ export class EwtInstallDialog extends LitElement { text-decoration: underline; cursor: pointer; } - :host([state="LOGS"]) ewt-dialog { - --mdc-dialog-max-width: 90vw; + :host([state="LOGS"]) ew-dialog { + max-width: 90vw; + max-height: 90vh; } ewt-console { width: calc(80vw - 48px); - height: 80vh; - } - ewt-list-item[value="-1"] { - border-top: 1px solid #ccc; + height: calc(90vh - 168px); } `, ]; diff --git a/src/no-port-picked/no-port-picked-dialog.ts b/src/no-port-picked/no-port-picked-dialog.ts index 935cd1ef..b01e7da2 100644 --- a/src/no-port-picked/no-port-picked-dialog.ts +++ b/src/no-port-picked/no-port-picked-dialog.ts @@ -1,7 +1,8 @@ import { LitElement, html, css, svg } from "lit"; import { customElement } from "lit/decorators.js"; -import "../components/ewt-dialog"; -import "../components/ewt-button"; +import "../components/ew-dialog"; +import "../components/ew-text-button"; + import { dialogStyles } from "../styles"; import { getOperatingSystem } from "../util/get-operating-system"; @@ -34,120 +35,116 @@ class EwtNoPortPickedDialog extends LitElement { const OS = getOperatingSystem(); return html` - -
- If you didn't select a port because you didn't see your device listed, - try the following steps: -
-
    -
  1. - Make sure that the device is connected to this computer (the one - that runs the browser that shows this website) -
  2. -
  3. - Most devices have a tiny light when it is powered on. If yours has - one, make sure it is on. -
  4. -
  5. - Make sure that the USB cable you use can be used for data and is not - a power-only cable. -
  6. - ${OS === "Linux" - ? html` + +
    No port selected
    +
    +
    + If you didn't select a port because you didn't see your device + listed, try the following steps: +
    +
      +
    1. + Make sure that the device is connected to this computer (the one + that runs the browser that shows this website) +
    2. +
    3. + Most devices have a tiny light when it is powered on. If yours has + one, make sure it is on. +
    4. +
    5. + Make sure that the USB cable you use can be used for data and is + not a power-only cable. +
    6. + ${OS === "Linux" + ? html` +
    7. + If you are using a Linux flavor, make sure that your user is + part of the dialout group so it has permission + to access the device. + sudo usermod -a -G dialout YourUserName + You may need to log out & back in or reboot to activate the + new group access. +
    8. + ` + : ""} +
    9. + Make sure you have the right drivers installed. Below are the + drivers for common chips used in ESP devices: +
        +
      • + CP2102 drivers: + Windows & Mac +
      • +
      • + CH342, CH343, CH9102 drivers: + Windows, + Mac +
        + (download via blue button with ${cloudDownload} icon) +
      • - If you are using a Linux flavor, make sure that your user is - part of the dialout group so it has permission to - access the device. - sudo usermod -a -G dialout YourUserNameWindows, + Mac - You may need to log out & back in or reboot to activate the - new group access. +
        + (download via blue button with ${cloudDownload} icon)
      • +
      +
    10. +
    +
    +
    + ${this.doTryAgain + ? html` + Cancel + + Try Again + ` - : ""} -
  7. - Make sure you have the right drivers installed. Below are the - drivers for common chips used in ESP devices: -
      -
    • - CP2102 drivers: - Windows & Mac -
    • -
    • - CH342, CH343, CH9102 drivers: - Windows, - Mac -
      - (download via blue button with ${cloudDownload} icon) -
    • -
    • - CH340, CH341 drivers: - Windows, - Mac -
      - (download via blue button with ${cloudDownload} icon) -
    • -
    -
  8. -
- ${this.doTryAgain - ? html` - - - - ` - : html` - - `} -
+ : html` + Close + `} +
+ `; } + private tryAgain() { + this.close(); + this.doTryAgain?.(); + } + + private close() { + this.shadowRoot!.querySelector("ew-dialog")!.close(); + } + private async _handleClose() { this.parentNode!.removeChild(this); } diff --git a/src/pages/ewt-page-message.ts b/src/pages/ewt-page-message.ts index 5a99721e..3d5517bd 100644 --- a/src/pages/ewt-page-message.ts +++ b/src/pages/ewt-page-message.ts @@ -1,6 +1,5 @@ import { LitElement, html, css, TemplateResult } from "lit"; import { property } from "lit/decorators.js"; -import "../components/ewt-circular-progress"; class EwtPageMessage extends LitElement { @property() icon!: string; @@ -25,9 +24,6 @@ class EwtPageMessage extends LitElement { line-height: 80px; color: black; } - ewt-circular-progress { - margin-bottom: 16px; - } `; } customElements.define("ewt-page-message", EwtPageMessage); diff --git a/src/pages/ewt-page-progress.ts b/src/pages/ewt-page-progress.ts index fa282fe5..cac71e2b 100644 --- a/src/pages/ewt-page-progress.ts +++ b/src/pages/ewt-page-progress.ts @@ -1,6 +1,6 @@ import { LitElement, html, css, TemplateResult } from "lit"; import { property } from "lit/decorators.js"; -import "../components/ewt-circular-progress"; +import "../components/ew-circular-progress"; class EwtPageProgress extends LitElement { @property() label!: string | TemplateResult; @@ -10,14 +10,13 @@ class EwtPageProgress extends LitElement { render() { return html`
- + > ${this.progress !== undefined ? html`
${this.progress}%
` : ""}
${this.label} @@ -30,7 +29,7 @@ class EwtPageProgress extends LitElement { flex-direction: column; text-align: center; } - ewt-circular-progress { + ew-circular-progress { margin-bottom: 16px; } `; diff --git a/src/styles.ts b/src/styles.ts index 58c1e419..b26fcef3 100644 --- a/src/styles.ts +++ b/src/styles.ts @@ -6,29 +6,26 @@ import { css } from "lit"; export const dialogStyles = css` :host { - --mdc-theme-primary: var(--improv-primary-color, #03a9f4); - --mdc-theme-on-primary: var(--improv-on-primary-color, #fff); - --improv-danger-color: #db4437; - --improv-text-color: rgba(0, 0, 0, 0.6); - --mdc-theme-text-primary-on-background: var(--improv-text-color); - --mdc-dialog-content-ink-color: var(--improv-text-color); - text-align: left; - font-size: 16px; - --mdc-typography-headline6-font-size: 1.25em; - --mdc-typography-headline6-line-height: 2em; - --mdc-typography-body1-font-size: 1em; - --mdc-typography-body1-line-height: 1.5em; - --mdc-typography-button-font-size: 0.875em; - --mdc-typography-button-line-height: 2.25em; - --mdc-typography-subtitle1-font-size: 1em; - --mdc-typography-subtitle1-line-height: 1.75em; - } + --roboto-font: Roboto, system-ui; + --text-color: rgba(0, 0, 0, 0.6); + --danger-color: #db4437; - a { - color: var(--improv-primary-color, #03a9f4); + --md-sys-color-primary: #03a9f4; + --md-sys-color-on-primary: #fff; + --md-ref-typeface-brand: var(--roboto-font); + --md-ref-typeface-plain: var(--roboto-font); + + --md-sys-color-surface: #fff; + --md-sys-color-surface-container: #fff; + --md-sys-color-surface-container-high: #fff; + --md-sys-color-surface-container-highest: #f5f5f5; + --md-sys-color-secondary-container: #e0e0e0; + + --md-sys-typescale-headline-font: var(--roboto-font); + --md-sys-typescale-title-font: var(--roboto-font); } - a.button { - text-decoration: none; + a { + color: var(--md-sys-color-primary); } `;