Eigenes Zifferblatt bauen
Bau eigene Zifferblätter für deine Anzeigen mit HTML, CSS und JavaScript. Jedes Zifferblatt funktioniert mit jeder Quelle, von der Batterie bis zu Zahlen, die du selbst schickst.
Schnellstart
- Zifferblatt anlegen: Klick in den Einstellungen auf Zifferblatt erstellen… (Wahltaste-Befehlstaste-N). Multimeter legt einen Ordner mit Startdateien an, die schon die Daten der Version 2 nutzen.
- Dateien bearbeiten: Multimeter zeigt den Ordner im Finder. Bearbeite die Dateien in einem beliebigen Code-Editor.
- Änderungen live sehen: Multimeter lädt dein Zifferblatt bei jedem Speichern neu. Probier es unter Anzeige hinzufügen… oder Diese Anzeige anpassen… mit verschiedenen Quellen aus.
- Teilen: Komprimiere den Ordner im Finder, benenne die .zip in
.multimeterum und reiche sie bei der Galerie ein. Jeder kann sie mit Importieren… (Befehlstaste-O) oder per Doppelklick auf die Datei hinzufügen.
So funktioniert eine Anzeige
Eine Anzeige in der Menüleiste ist ein Zifferblatt plus eine Quelle plus die Einstellungen der Person. Das Zifferblatt ist dein Ordner: eine kleine Webseite, die Multimeter in eine transparente Ansicht lädt, 22 Punkt hoch und so breit wie width in deinem Manifest. Die Quelle ist das, was die Anzeige misst, ausgewählt von der Person, wenn sie die Anzeige hinzufügt.
Sobald sich etwas ändert, setzt Multimeter window.meterData und schickt ein meterUpdate-Ereignis. Dein Zifferblatt muss nicht wissen, woher die Zahlen kommen: Zeichne level (0 bis 1) und zeig formatted, dann funktioniert es für CPU, Netzwerk, einen Timer oder die Batterie gleichermaßen.
Dateistruktur
Jedes Zifferblatt ist ein Ordner mit:
my-meter/
├── manifest.json # name, size, which sources it's made for
├── index.html # the page Multimeter loads
├── styles.css
└── meter.js # listens for meterUpdate and drawsmanifest.json
Das Manifest beschreibt dein Zifferblatt und sagt Multimeter, wie breit es ist und wofür es gemacht ist:
{
"name": "My Meter",
"description": "What it shows, in one line.",
"version": "1.0.0",
"author": "Your Name",
"apiVersion": 2,
"sources": ["any"],
"defaultSource": "cpu",
"width": 60,
"minWidth": 40,
"maxWidth": 100,
"supportsLightMode": true,
"supportsDarkMode": true
}| Schlüssel | Typ | Bedeutung |
|---|---|---|
name | string | Erscheint in der Zifferblattliste und in der Galerie. |
description | string | Eine Zeile dazu, was das Zifferblatt zeigt. |
version | string | Deine Versionsnummer, etwa 1.0.0. |
author | string | Dein Name, angezeigt in der Galerie. |
apiVersion | 2 | Setz das auf 2 für die Daten, die auf dieser Seite beschrieben sind. |
sources | string[] | ["any"] für ein Zifferblatt, das jede Quelle zeichnen kann, oder eine Liste von Quell-IDs wie ["battery"] oder ["battery", "countdown", "timer"]. Multimeter bietet dein Zifferblatt nur für diese Quellen an. |
defaultSource | string | Die Quelle, die ausgewählt ist, wenn jemand dein Zifferblatt zum ersten Mal hinzufügt, etwa "cpu". |
width | number | Breite in Punkt. Die Höhe ist immer 22. |
minWidth / maxWidth | number | Die geringste und größte Breite, die die Person unter Anpassen einstellen kann. |
supportsLightMode / supportsDarkMode | boolean | Ob das Zifferblatt für helle und dunkle Menüleisten gestaltet ist. |
Ein Manifest ohne apiVersion und sources gilt als Zifferblatt mit Fokus auf die Batterie, das trotzdem mit jeder Quelle funktioniert. So laufen Anzeigen für frühere Versionen weiter.
Anzeigedaten
Multimeter legt die aktuellen Daten in window.meterData ab und schickt sie bei jeder Änderung erneut. Das ist alles, was drinsteckt (API-Version 2):
window.meterData = {
apiVersion: 2,
source: "cpu", // what this meter measures
sourceName: "CPU", // that source's name, translated
label: "CPU", // the meter's label ("" if the person cleared it)
value: 23.4, // raw value in `unit` (null if unavailable)
min: 0, max: 100, // the range `level` is measured against
level: 0.234, // value placed in the range, 0 to 1
formatted: "23%", // ready to show, unit included, in the person's language
unit: "%", // "%", "W", "B/s", "rpm", "s", or your own
state: "normal", // "normal", "warning" or "critical"
tint: null, // "#30D158" if the person picked a color
history: [0.21, 0.25], // up to 60 recent levels, oldest first
warningLevel: 0.7, // alert levels on the same 0 to 1 scale (or null)
criticalLevel: 0.9,
alertDirection: "above", // "above" or "below" (or null)
available: true, // false when the source can't be read right now
colorScheme: "dark", // the menu bar: "light" or "dark"
reduceMotion: false, // System Settings > Accessibility > Reduce motion
strings: { timeLeft: "left" },
battery: { // always the Mac's battery, whatever the source
level: 0.82, percentage: 82, isCharging: false, isPluggedIn: false,
hasBattery: true, timeRemaining: 312, timeToFullCharge: null,
formattedTime: "5:12", cycleCount: 212, health: 0.94, temperature: 30.5
},
// Version 1 fields, so battery meters keep working with any source:
percentage: 23, isCharging: false, isPluggedIn: false,
timeRemaining: null, timeToFullCharge: null, formattedTime: null,
cycleCount: 212, health: 0.94, temperature: 30.5, hasBattery: true
}| Feld | Bedeutung |
|---|---|
source | Die Quell-ID (siehe Tabelle unten). sourceName ist ihr übersetzter Name. |
label | Die Beschriftung der Anzeige, etwa CPU oder DOWN. Die Person kann sie umbenennen oder leeren, es kann also ein leerer String sein. |
value | Der Rohwert in unit oder null. Zusammen mit min und max hast du das ganze Bild. |
level | Der Wert, eingeordnet in den Bereich von 0 bis 1 und begrenzt. Die meisten Zifferblätter brauchen nur das. |
formatted | Der Messwert als Text, inklusive Einheit und passend zur Sprache der Person formatiert: 23%, 12.4 W, 1.2 MB/s, 4:12. |
unit | %, W, B/s, rpm, s (Timer und Countdowns), ein leerer String oder die eigene Einheit der Person. |
state | normal, warning oder critical, je nach den Warnstufen, die die Person festgelegt hat. Färbe dich danach. |
tint | Eine Farbe wie #30D158, die die Person gewählt hat, oder null, damit dein Zifferblatt seine eigenen Farben nutzt. |
history | Bis zu 60 letzte Füllstände (0 bis 1), die ältesten zuerst, für Diagramme. |
warningLevel | warningLevel und criticalLevel legen die Warnstufen auf dieselbe Skala von 0 bis 1 wie level, und alertDirection sagt, ob Warnungen above oder below davon auslösen. Alle drei sind null, wenn die Anzeige keine Warnungen hat. |
available | false, wenn sich die Quelle gerade nicht lesen lässt: keine Batterie, das Zubehör ist aus, eine Webadresse antwortet nicht. Zeig einen Strich. |
colorScheme | Das Aussehen der Menüleiste, light oder dark. Es richtet sich nach dem Hintergrundbild, nicht nur nach der Systemeinstellung. |
reduceMotion | true, wenn Bewegung reduzieren aktiv ist. Lass Animationen weg. |
battery | Die Batterie des Macs, immer vorhanden, egal was die Anzeige misst: Ladestand, Laden, angeschlossen, Restzeit, Zeit bis voll, Zyklen, Zustand und Temperatur. |
Auf Updates hören
Zeichne einmal mit dem, was schon in window.meterData steht, und dann bei jedem meterUpdate erneut. Setz window.meterReady = true, sobald du bereit für Daten bist.
function render(data) {
// draw the meter from data.level, data.formatted, data.state ...
}
window.addEventListener('meterUpdate', (e) => render(e.detail));
render(window.meterData || { level: 0.5, formatted: '50%', state: 'normal' });
window.meterReady = true;Quellen
Das sind die Quellen, die eine Anzeige haben kann. Dein Zifferblatt sieht die ID in source und bekommt formatted schon fertig geschrieben, du musst sie also selten unterschiedlich behandeln.
| Quelle | source | unit | formatted sieht so aus |
|---|---|---|---|
| Batterie | battery | "%" | 82% |
| Bluetooth-Zubehör | bluetooth | "%" | 64% |
| Leistungsaufnahme | power | "W" | 12.4 W |
| CPU | cpu | "%" | 23% |
| Arbeitsspeicher | memory | "%" | 71% |
| Speicherplatz | disk | "%" | 58% |
| Thermische Last | thermal | "" | Normal, Erhöht, Hoch, Kritisch |
| Lüftergeschwindigkeit* | fan | "rpm" | 2,400 rpm |
| Netzwerk | network | "B/s" | 1.2 MB/s, 340 KB/s |
| Timer | timer | "s" | 24:51 |
| Countdown | countdown | "s" | 3d 4h, 4:12, 12:05 |
| Tagesfortschritt | progress | "%" | 63% |
| Gesendeter Wert | push | "" | 42 |
| Webadresse | url | "" | 1,284 |
| Datei | file | "" | 12 |
| Skript* | script | "" | 412 |
* Lüftergeschwindigkeit und Skripte brauchen die Version von Multimeter zum direkten Download. Die Version aus dem Mac App Store kann die Lüftersensoren nicht lesen und keine Skripte ausführen; nimm dort stattdessen einen gesendeten Wert oder eine Datei.
Prozentwerte laufen immer von 0 bis 100. Leistung, Netzwerk und Lüftergeschwindigkeit skalieren auf ihren jüngsten Spitzenwert, außer die Person legt einen Bereich fest. Die thermische Last hat vier Stufen, level ist also 0, 0.33, 0.67 oder 1. Bei Timern und Countdowns ist level der Anteil der verbleibenden Zeit und value die verbleibenden Sekunden.
Warnungen und Farben
Jede Anzeige kann eine Warnstufe und eine kritische Stufe haben, festgelegt von der Person (Batterie standardmäßig unter 20% und 10%, CPU über 70% und 90%, Speicherplatz über 85% und 95%). Multimeter berechnet state für dich. Ein Zifferblatt sollte bei normal ruhig aussehen, bei warning und critical lauter werden und tint verwenden, wenn die Person eine Farbe gewählt hat:
document.body.classList.remove('warning', 'critical');
if (data.state !== 'normal') document.body.classList.add(data.state);
// The person's color wins over the face's own
if (data.tint) document.body.style.setProperty('--accent', data.tint);
else document.body.style.removeProperty('--accent');body.warning { --accent: #ff9f0a; }
body.critical { --accent: #ff453a; }Du willst die Warnbereiche auf einer Skala zeichnen, etwa ein Zeigerinstrument mit rotem Ende? Nimm warningLevel, criticalLevel und alertDirection.
Verlauf
history enthält bis zu 60 letzte Füllstände, die ältesten zuerst, schon auf der Skala von 0 bis 1. Häng den aktuellen level ans Ende, und du hast ein Diagramm. Das Beispiel Verlaufsdiagramm unten zeichnet eins.
Batteriedetails
Die Batterie ist immer noch etwas Besonderes. data.battery ist immer die Batterie des Macs, egal was die Anzeige misst, so kann jedes Zifferblatt einen Ladeblitz zeigen. Ein Zifferblatt nur für die Batterie sollte in seinem Manifest "sources": ["battery"] angeben. timeRemaining und timeToFullCharge sind in Minuten und null, solange macOS noch schätzt.
// A battery-only face: "sources": ["battery"] in manifest.json
const b = data.battery;
bolt.hidden = !b.isCharging;
time.textContent = b.isCharging
? (b.timeToFullCharge ? `${b.timeToFullCharge} min to full` : '')
: (b.formattedTime ?? '');Zifferblätter für Version 1 lesen percentage, isCharging und formattedTime auf oberster Ebene. Die werden weiterhin geschickt: Für die Batteriequelle sind es die Werte der Batterie, bei anderen Quellen ist isCharging false und formattedTime die Restzeit eines Timers oder Countdowns (h:mm), sonst null.
Deine eigenen Daten
Vier Quellen zeigen Zahlen, die du lieferst: ein gesendeter Wert, eine Webadresse, eine Datei oder ein Skript. Dein Zifferblatt behandelt sie wie jede andere Quelle.
Einen Wert per Link schicken
Öffne einen multimeter://set-Link von überall: Terminal, ein Shell-Skript, Kurzbefehle (URLs öffnen), Raycast, ein cron-Job, ein Build-Skript. Füg eine Anzeige mit der Quelle Gesendeter Wert und demselben Schlüssel hinzu, und sie aktualisiert sich, sobald der Link geöffnet wird. open -g lässt Multimeter im Hintergrund.
# Set a value (the meter shows the "deploys" key)
open -g "multimeter://set?key=deploys&value=42"
# Range, label, unit and your own text ride along
open -g "multimeter://set?key=coffee&value=3&min=0&max=5&label=Coffee&unit=cups"
open -g "multimeter://set?key=build&value=0.8&max=1&formatted=80%25%20done"| Parameter | Bedeutung |
|---|---|
key | Für welche Anzeige er gedacht ist. Groß- und Kleinschreibung spielt bei Schlüsseln keine Rolle. |
value | Die Zahl. Pflichtangabe. |
min / max | Der Bereich, damit level stimmt. Standard ist 0 bis 100. |
label | Text für die Beschriftung der Anzeige. |
unit | Eine Einheit hinter der Zahl, etwa cups. Nimm % für einen Prozentwert. |
formatted | Dein eigener Text für formatted, statt der Zahl. |
Gesendete Werte funktionieren auch in der Version aus dem Mac App Store. Multimeter merkt sich den letzten Wert für jeden Schlüssel.
Webadressen, Dateien und Skripte
Alle drei lesen dieselbe Ausgabe: eine reine Zahl oder JSON mit einem value und beliebigen Extras. Alles außer value ist optional.
42
42.5
42%
{"value": 42, "min": 0, "max": 100, "label": "Deploys", "unit": "", "formatted": "42 left"}Zeigst du auf größeres JSON, etwa eine API-Antwort? Gib der Anzeige einen Schlüsselpfad, und sie holt die Zahl heraus:
{"data": {"count": 17}} → key path data.count
{"items": [{"value": 9.5}]} → key path items.0.value- Webadresse: abgerufen in einem Intervall deiner Wahl, höchstens alle 30 Sekunden (alle 5 Minuten, wenn du nichts änderst).
- Datei: wird neu gelesen, sobald sich die Datei ändert. Praktisch für alles, was eine Datei schreiben kann.
- Skript: ein Shell-Befehl, ausgeführt mit
zshin einem Intervall deiner Wahl (alle 30 Sekunden, wenn du nichts änderst). Multimeter zeigt die Zahl, die er ausgibt. Die Ordner von Homebrew sind imPATH, und ein Befehl, der länger als 10 Sekunden braucht, wird gestoppt.
# Open pull requests waiting on you (direct download version)
gh pr list --search "review-requested:@me" --json number --jq length
# Free memory pressure as a percentage
memory_pressure | awk '/percentage/ {print 100 - $5}'Die Version aus dem Mac App Store kann Webadressen und Dateien nutzen, aber keine Skripte. Lass dein Skript dort stattdessen einen Link schicken oder eine Datei schreiben.
Helle und dunkle Menüleisten
Die Menüleiste ist je nach Hintergrundbild hell oder dunkel. Multimeter fügt body die Klasse light-mode oder dark-mode hinzu, setzt colorScheme in den Daten, und auch prefers-color-scheme passt zur Menüleiste. Nimm, was dir lieber ist:
/* Dark menu bar (the default) */
body { color: white; }
/* Light menu bar */
body.light-mode { color: black; }
/* Same thing with the media query, which follows the menu bar too */
@media (prefers-color-scheme: light) {
body { color: black; }
}Reduzierte Bewegung
Wenn Bewegung reduzieren aktiv ist, ist reduceMotion true und prefers-reduced-motion greift. Halte die Anzeige lesbar und lass Hüpfen, Pulsieren und Wischen weg:
body.reduce-motion * { transition: none !important; animation: none !important; }
@media (prefers-reduced-motion: reduce) {
* { transition: none !important; animation: none !important; }
}Vollständige Beispiele
Zwei vollständige Zifferblätter, die auf dieser Seite live mit denselben Daten laufen, die Multimeter schickt. Kopier die Dateien in einen Ordner und importiere ihn.
Die Vorlage von Zifferblatt erstellen
Genau das, was Zifferblatt erstellen… schreibt: eine Beschriftung, ein Balken und der formatierte Wert, mit der API in den Kommentaren. Es färbt sich nach state, beachtet tint und folgt dem Aussehen der Menüleiste.
starter/manifest.json
{
"name": "My Face",
"description": "A label, a bar and the value. Works with any source.",
"version": "1.0.0",
"author": "Your Name",
"apiVersion": 2,
"sources": ["any"],
"defaultSource": "cpu",
"width": 70,
"minWidth": 50,
"maxWidth": 120,
"supportsLightMode": true,
"supportsDarkMode": true
}starter/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div id="meter">
<span id="label"></span>
<span id="track"><span id="fill"></span></span>
<span id="value">--</span>
</div>
<script src="meter.js"></script>
</body>
</html>starter/styles.css
* { margin: 0; padding: 0; box-sizing: border-box; }
/* The meter is 22 points tall and as wide as manifest.json says. */
body {
font: 600 11px/1 -apple-system, BlinkMacSystemFont, sans-serif;
font-variant-numeric: tabular-nums;
color: white; /* dark menu bar */
background: transparent;
height: 22px;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
--accent: #30d158; /* replaced by the meter's color, if one is set */
}
/* Light menu bar: the system setting, or the preview's light mode. */
#track { background: rgba(255, 255, 255, 0.25); }
@media (prefers-color-scheme: light) { body { color: black; } #track { background: rgba(0, 0, 0, 0.18); } }
body.light-mode { color: black; }
body.light-mode #track { background: rgba(0, 0, 0, 0.18); }
body.dark-mode { color: white; }
body.dark-mode #track { background: rgba(255, 255, 255, 0.25); }
#meter { display: flex; align-items: center; gap: 4px; }
#label { font-size: 8px; letter-spacing: 0.04em; opacity: 0.7; }
#track { width: 18px; height: 6px; border-radius: 3px; position: relative; overflow: hidden; }
#fill { position: absolute; inset: 0 auto 0 0; width: 0; background: var(--accent); border-radius: 3px; transition: width 0.4s ease; }
/* state is "normal", "warning" or "critical" (from the meter's alert levels). */
body.warning { --accent: #ffd60a; }
body.critical { --accent: #ff453a; }
@media (prefers-reduced-motion: reduce) { #fill { transition: none; } }starter/meter.js
// Multimeter meter API, version 2. The app sets window.meterData and fires
// a 'meterUpdate' event whenever anything changes. The fields you'll use most:
//
// level 0.0 to 1.0, the value within the meter's range
// formatted ready-to-show text with its unit: "23%", "1.2 MB/s", "4:12"
// label short label ("CPU"), may be "" if hidden
// value, unit, min, max the raw number and its range
// state "normal", "warning" or "critical"
// tint the color picked in Customize ("#30D158"), or null
// history up to 60 recent levels (0 to 1), oldest first, for graphs
// source what it measures: "battery", "cpu", "memory", "network", "timer"...
// available false when there's nothing to read (no battery, URL failing)
// battery the Mac's battery, always: level, isCharging, isPluggedIn,
// hasBattery, timeRemaining, timeToFullCharge, health...
// isCharging true only when this meter shows the battery and it's charging
// colorScheme "light" or "dark"; reduceMotion true if animations should stop
//
// Full reference: https://multimeterapp.com/creating-meters
class Meter {
constructor() {
this.label = document.getElementById('label');
this.fill = document.getElementById('fill');
this.value = document.getElementById('value');
window.addEventListener('meterUpdate', (e) => this.render(e.detail));
if (window.meterData) this.render(window.meterData);
window.meterReady = true;
}
render(data) {
const level = Math.max(0, Math.min(1, data.level || 0));
this.label.textContent = data.label || '';
this.label.style.display = data.label ? '' : 'none';
this.value.textContent = data.available === false ? '\u2013' : (data.formatted || Math.round(level * 100) + '%');
this.fill.style.width = (level * 100) + '%';
document.body.classList.toggle('warning', data.state === 'warning');
document.body.classList.toggle('critical', data.state === 'critical');
if (data.tint) document.body.style.setProperty('--accent', data.tint);
else document.body.style.removeProperty('--accent');
}
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => new Meter());
} else {
new Meter();
}Verlaufsdiagramm
Ein Liniendiagramm der letzten Minute aus history, auf ein Canvas in der echten Auflösung des Bildschirms gezeichnet.
history-graph/manifest.json
{
"name": "History Graph",
"description": "The last minute as a little line graph.",
"version": "1.0.0",
"author": "Your Name",
"apiVersion": 2,
"sources": ["any"],
"defaultSource": "network",
"width": 44,
"minWidth": 30,
"maxWidth": 80,
"supportsLightMode": true,
"supportsDarkMode": true
}history-graph/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
html, body { margin: 0; height: 22px; background: transparent; overflow: hidden; }
canvas { display: block; width: 100%; height: 22px; }
</style>
</head>
<body>
<canvas id="graph"></canvas>
<script src="meter.js"></script>
</body>
</html>history-graph/meter.js
const canvas = document.getElementById('graph');
const ctx = canvas.getContext('2d');
function render(data) {
// Draw at the screen's real resolution so the line stays sharp
const scale = window.devicePixelRatio || 1;
const w = canvas.clientWidth, h = 22;
canvas.width = w * scale;
canvas.height = h * scale;
ctx.setTransform(scale, 0, 0, scale, 0, 0);
ctx.clearRect(0, 0, w, h);
const points = (data.history || []).concat(data.level ?? 0);
if (points.length < 2) return;
const dark = data.colorScheme !== 'light';
const color = data.tint
|| (data.state === 'critical' ? '#ff453a' : data.state === 'warning' ? '#ff9f0a' : dark ? '#fff' : '#1d1d1f');
const x = (i) => (i / (points.length - 1)) * (w - 2) + 1;
const y = (v) => h - 3 - v * (h - 6);
// Soft fill under the line, then the line
ctx.beginPath();
points.forEach((v, i) => (i ? ctx.lineTo(x(i), y(v)) : ctx.moveTo(x(i), y(v))));
ctx.lineTo(x(points.length - 1), h);
ctx.lineTo(x(0), h);
ctx.closePath();
ctx.globalAlpha = 0.22;
ctx.fillStyle = color;
ctx.fill();
ctx.globalAlpha = 1;
ctx.beginPath();
points.forEach((v, i) => (i ? ctx.lineTo(x(i), y(v)) : ctx.moveTo(x(i), y(v))));
ctx.strokeStyle = color;
ctx.lineWidth = 1.5;
ctx.lineJoin = 'round';
ctx.stroke();
}
window.addEventListener('meterUpdate', (e) => render(e.detail));
render(window.meterData || { history: [0.2, 0.4, 0.3, 0.6, 0.5], level: 0.7 });
window.meterReady = true;Tipps zum Testen
- Bleib innerhalb von 22 Punkt Höhe und prüfe dein Zifferblatt bei
minWidthundmaxWidth. - Nutze die Systemschrift (
-apple-system) undfont-variant-numeric: tabular-nums, damit Zahlen nicht springen. - Probier dein Zifferblatt unter Anzeige hinzufügen… und Diese Anzeige anpassen… mit mehreren Quellen aus: einem Prozentwert, Netzwerktempo, einem Timer, einer nicht verfügbaren Quelle.
- Prüfe helle und dunkle Menüleisten, eine Farbe sowie die Zustände Warnung und kritisch.
- Fehler aus deinem JavaScript erscheinen in Console.app. Du kannst deine
index.htmlauch in Safari öffnen und ihr über die Konsole Daten schicken: - Halte die Dateien klein und verzichte auf Netzwerkanfragen, damit das Zifferblatt sofort erscheint.
// Paste in Safari's console with your index.html open to try a value
window.meterData = { level: 0.92, formatted: '92%', label: 'CPU', state: 'critical',
available: true, colorScheme: 'dark', history: [] };
window.dispatchEvent(new CustomEvent('meterUpdate', { detail: window.meterData }));Bereit loszulegen?
$19.99 einmalig. Kein Abo. 30 Tage Geld zurück.
Für $19.99 kaufen