diff --git a/apps/web/public/i18n/locales/en/map.json b/apps/web/public/i18n/locales/en/map.json
index c1cf0f63d..2bbfd1ddc 100644
--- a/apps/web/public/i18n/locales/en/map.json
+++ b/apps/web/public/i18n/locales/en/map.json
@@ -14,6 +14,7 @@
"positionPrecision": "Show position precision",
"traceroutes": "Show traceroutes",
"waypoints": "Show waypoints",
+ "geofences": "Show geofences",
"heatmap": "Show heatmap",
"density": "Density"
},
@@ -32,7 +33,71 @@
"bearing": "Absolute bearing:",
"lockedTo": "Locked by:",
"latitude": "Latitude:",
- "longitude": "Longitude:"
+ "longitude": "Longitude:",
+ "geofenceRadius": "Geofence radius:",
+ "notifications": "Alerts:",
+ "enter": "enter",
+ "exit": "exit",
+ "favoritesOnly": "favorites only",
+ "editGeofence": "Edit geofence",
+ "addGeofence": "Add geofence"
+ },
+ "waypointEdit": {
+ "title": "Edit waypoint – {{name}}",
+ "titleCreate": "New waypoint",
+ "name": "Name",
+ "description": "Description",
+ "icon": "Icon",
+ "latitude": "Latitude",
+ "longitude": "Longitude",
+ "expiresAt": "Expires",
+ "radius": "Geofence radius",
+ "radiusHint": "0 to disable the circular geofence.",
+ "boundingBox": "Bounding box",
+ "west": "West",
+ "south": "South",
+ "east": "East",
+ "north": "North",
+ "captureFromMap": "Use current map view",
+ "notifyOnEnter": "Alert on enter",
+ "notifyOnExit": "Alert on exit",
+ "notifyFavoritesOnly": "Favorites only",
+ "save": "Save & broadcast",
+ "saving": "Saving…",
+ "cancel": "Cancel",
+ "savedToast": "Waypoint saved: {{name}}",
+ "createdToast": "Waypoint created: {{name}}",
+ "errorToast": "Could not save waypoint",
+ "errorMissingName": "Waypoint needs a name",
+ "errorBadCoords": "Latitude and longitude are required",
+ "enterToast": "{{node}} entered {{waypoint}}",
+ "exitToast": "{{node}} left {{waypoint}}",
+ "viewOnMap": "View on map",
+ "newWaypointAria": "New waypoint",
+ "placementHint": "Click on the map to place your waypoint",
+ "drawHint": "Drag on the map to define the bounding box",
+ "drawBox": "Draw box",
+ "editBox": "Edit box",
+ "removeBox": "Remove box",
+ "radiusOff": "Off"
+ },
+ "unit": {
+ "meter": {
+ "one": "meter",
+ "plural": "meters"
+ },
+ "kilometer": {
+ "plural": "km"
+ },
+ "foot": {
+ "plural": "ft"
+ },
+ "mile": {
+ "plural": "mi"
+ },
+ "degree": {
+ "suffix": "°"
+ }
},
"myNode": {
"tooltip": "This device"
diff --git a/apps/web/src/App.tsx b/apps/web/src/App.tsx
index 67f0b89c7..b358647cd 100644
--- a/apps/web/src/App.tsx
+++ b/apps/web/src/App.tsx
@@ -7,6 +7,7 @@ import { RegionSetupReminder } from "@components/RegionSetupReminder.tsx";
import { Toaster } from "@components/Toaster.tsx";
import { ErrorPage } from "@components/UI/ErrorPage.tsx";
import Footer from "@components/UI/Footer.tsx";
+import { useGeofenceAlerts } from "@core/hooks/useGeofenceAlerts.ts";
import { useTheme } from "@core/hooks/useTheme.ts";
import { SidebarProvider, useAppStore, useDeviceStore } from "@core/stores";
import { Connections } from "@pages/Connections/index.tsx";
@@ -15,6 +16,11 @@ import { TanStackRouterDevtools } from "@tanstack/react-router-devtools";
import { ErrorBoundary } from "react-error-boundary";
import { MapProvider } from "react-map-gl/maplibre";
+const GeofenceAlertsBridge = () => {
+ useGeofenceAlerts();
+ return null;
+};
+
export function App() {
useTheme();
@@ -41,6 +47,7 @@ export function App() {
{device ? (
+
diff --git a/apps/web/src/components/Dialog/WaypointEditDialog.test.tsx b/apps/web/src/components/Dialog/WaypointEditDialog.test.tsx
new file mode 100644
index 000000000..102ff4f99
--- /dev/null
+++ b/apps/web/src/components/Dialog/WaypointEditDialog.test.tsx
@@ -0,0 +1,232 @@
+import { create } from "@bufbuild/protobuf";
+import type { WaypointWithMetadata } from "@core/stores";
+import { act, fireEvent, render, screen } from "@testing-library/react";
+import { Protobuf } from "@meshtastic/sdk";
+import type {
+ ButtonHTMLAttributes,
+ InputHTMLAttributes,
+ ReactNode,
+} from "react";
+import { beforeEach, describe, expect, it, vi } from "vitest";
+import { WaypointEditDialog } from "./WaypointEditDialog.tsx";
+
+const mockToast = vi.fn();
+vi.mock("@core/hooks/useToast.ts", () => ({
+ useToast: () => ({ toast: mockToast }),
+}));
+
+const sendWaypoint = vi.fn().mockResolvedValue(0);
+const addWaypoint = vi.fn();
+vi.mock("@core/stores", () => ({
+ useDevice: () => ({
+ hardware: { myNodeNum: 1 },
+ connection: { sendWaypoint },
+ addWaypoint,
+ // Metric device — matches the presets asserted below.
+ config: { display: { units: 0 } },
+ }),
+}));
+
+vi.mock("react-i18next", () => ({
+ useTranslation: () => ({
+ t: (key: string, opts?: Record
) =>
+ opts ? `${key} ${JSON.stringify(opts)}` : key,
+ }),
+}));
+
+vi.mock("@components/UI/Dialog.tsx", () => ({
+ Dialog: ({ open, children }: { open: boolean; children: ReactNode }) =>
+ open ? {children}
: null,
+ DialogContent: ({ children }: { children: ReactNode }) => (
+ {children}
+ ),
+ DialogHeader: ({ children }: { children: ReactNode }) => (
+ {children}
+ ),
+ DialogTitle: ({ children }: { children: ReactNode }) => {children}
,
+ DialogDescription: ({ children }: { children: ReactNode }) => (
+ {children}
+ ),
+ DialogClose: () => null,
+ DialogFooter: ({ children }: { children: ReactNode }) => (
+ {children}
+ ),
+}));
+
+vi.mock("@components/UI/Button.tsx", () => ({
+ Button: (props: ButtonHTMLAttributes) => (
+
+ ),
+}));
+
+vi.mock("@components/UI/Input.tsx", () => ({
+ Input: (props: InputHTMLAttributes) => ,
+}));
+
+vi.mock("@components/UI/Label.tsx", () => ({
+ Label: ({ children, ...rest }: { children: ReactNode }) => (
+
+ ),
+}));
+
+vi.mock("@components/UI/Switch.tsx", () => ({
+ Switch: ({
+ checked,
+ onCheckedChange,
+ id,
+ }: {
+ checked: boolean;
+ onCheckedChange: (v: boolean) => void;
+ id?: string;
+ }) => (
+ onCheckedChange(e.target.checked)}
+ />
+ ),
+}));
+
+function makeWaypoint(
+ fields: Record = {},
+): WaypointWithMetadata {
+ const wp = create(Protobuf.Mesh.WaypointSchema, fields as never);
+ return Object.assign(wp, {
+ metadata: { channel: 0, created: new Date(), from: 1 },
+ });
+}
+
+describe("WaypointEditDialog – geofence controls (design#114 compliance)", () => {
+ beforeEach(() => {
+ mockToast.mockClear();
+ sendWaypoint.mockClear();
+ addWaypoint.mockClear();
+ });
+
+ it("hides notify toggles until a radius or box is set", () => {
+ render(
+ {}}
+ waypoint={makeWaypoint({ id: 1, name: "Home" })}
+ initialLngLat={undefined}
+ channel={0}
+ mapRef={undefined}
+ onRequestBoundingBoxDraw={async () => undefined}
+ />,
+ );
+ expect(screen.queryByTestId("wp-notify-enter")).not.toBeInTheDocument();
+ expect(screen.queryByTestId("wp-notify-exit")).not.toBeInTheDocument();
+ expect(screen.queryByTestId("wp-notify-fav")).not.toBeInTheDocument();
+ });
+
+ it("reveals enter/exit toggles once a radius preset is selected; favorites-only revealed once enter is on", () => {
+ render(
+ {}}
+ waypoint={makeWaypoint({ id: 1, name: "Home" })}
+ initialLngLat={undefined}
+ channel={0}
+ mapRef={undefined}
+ onRequestBoundingBoxDraw={async () => undefined}
+ />,
+ );
+ // Metric locale (en-GB) → "500 meters"
+ const preset500 = screen.getByRole("button", {
+ name: /500 unit\.meter\.plural/i,
+ });
+ act(() => {
+ fireEvent.click(preset500);
+ });
+
+ expect(screen.getByTestId("wp-notify-enter")).toBeInTheDocument();
+ expect(screen.getByTestId("wp-notify-exit")).toBeInTheDocument();
+ // Favorites-only stays hidden until enter or exit is on
+ expect(screen.queryByTestId("wp-notify-fav")).not.toBeInTheDocument();
+
+ act(() => {
+ fireEvent.click(screen.getByTestId("wp-notify-enter"));
+ });
+ expect(screen.getByTestId("wp-notify-fav")).toBeInTheDocument();
+ });
+
+ it("draws box via the callback and shows Edit/Remove buttons afterwards", async () => {
+ const drawFn = vi.fn().mockResolvedValue({
+ west: -74.1,
+ south: 39.9,
+ east: -73.9,
+ north: 40.1,
+ });
+ render(
+ {}}
+ waypoint={makeWaypoint({ id: 1, name: "Home" })}
+ initialLngLat={undefined}
+ channel={0}
+ mapRef={{} as never}
+ onRequestBoundingBoxDraw={drawFn}
+ />,
+ );
+
+ await act(async () => {
+ fireEvent.click(
+ screen.getByRole("button", { name: /waypointEdit\.drawBox/i }),
+ );
+ });
+ expect(drawFn).toHaveBeenCalledOnce();
+ expect(
+ screen.getByRole("button", { name: /waypointEdit\.editBox/i }),
+ ).toBeInTheDocument();
+ expect(
+ screen.getByRole("button", { name: /waypointEdit\.removeBox/i }),
+ ).toBeInTheDocument();
+ });
+
+ it("save persists geofence fields on the outbound waypoint", async () => {
+ render(
+ {}}
+ waypoint={makeWaypoint({ id: 7, name: "Home" })}
+ initialLngLat={undefined}
+ channel={0}
+ mapRef={undefined}
+ onRequestBoundingBoxDraw={async () => undefined}
+ />,
+ );
+
+ // Pick 1 km preset (metric locale)
+ act(() => {
+ fireEvent.click(
+ screen.getByRole("button", { name: /1 unit\.kilometer\.plural/i }),
+ );
+ });
+ // Turn on enter alert
+ act(() => {
+ fireEvent.click(screen.getByTestId("wp-notify-enter"));
+ });
+ // Favorites-only
+ act(() => {
+ fireEvent.click(screen.getByTestId("wp-notify-fav"));
+ });
+
+ await act(async () => {
+ fireEvent.click(
+ screen.getByRole("button", { name: /waypointEdit\.save/i }),
+ );
+ });
+
+ expect(addWaypoint).toHaveBeenCalledOnce();
+ const [outbound] = addWaypoint.mock.calls[0]!;
+ expect(outbound.geofenceRadius).toBe(1000);
+ expect(outbound.notifyOnEnter).toBe(true);
+ expect(outbound.notifyOnExit).toBe(false);
+ expect(outbound.notifyFavoritesOnly).toBe(true);
+ expect(sendWaypoint).toHaveBeenCalledOnce();
+ });
+});
diff --git a/apps/web/src/components/Dialog/WaypointEditDialog.tsx b/apps/web/src/components/Dialog/WaypointEditDialog.tsx
new file mode 100644
index 000000000..a637f8077
--- /dev/null
+++ b/apps/web/src/components/Dialog/WaypointEditDialog.tsx
@@ -0,0 +1,551 @@
+import { clone, create } from "@bufbuild/protobuf";
+import { Button } from "@components/UI/Button.tsx";
+import {
+ Dialog,
+ DialogClose,
+ DialogContent,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+} from "@components/UI/Dialog.tsx";
+import { Input } from "@components/UI/Input.tsx";
+import { Label } from "@components/UI/Label.tsx";
+import { Switch } from "@components/UI/Switch.tsx";
+import { useToast } from "@core/hooks/useToast.ts";
+import { useDevice, type WaypointWithMetadata } from "@core/stores";
+import { cn } from "@core/utils/cn.ts";
+import type { LngLat } from "@core/utils/geo.ts";
+import {
+ coordToDeg,
+ degToCoordI,
+ displayToMeters,
+ metersToDisplay,
+ unitSystemFromDisplayUnits,
+} from "@core/utils/geofence.ts";
+import { generatePacketId, Protobuf } from "@meshtastic/sdk";
+import { useCallback, useEffect, useMemo, useState } from "react";
+import { useTranslation } from "react-i18next";
+import type { MapRef } from "react-map-gl/maplibre";
+
+const DEFAULT_ICON_CODEPOINT = 0x1f4cd; // 📍
+const WAYPOINT_NAME_MAX = 30;
+const WAYPOINT_DESC_MAX = 100;
+
+const METERS_PER_MILE = 1609.344;
+const METERS_PER_FOOT = 0.3048;
+const IMPERIAL_MILES_THRESHOLD_METERS = METERS_PER_MILE / 2;
+const METRIC_RADIUS_PRESETS_M = [0, 100, 500, 1_000, 5_000];
+const IMPERIAL_RADIUS_PRESETS_M = [
+ 0,
+ Math.round(0.1 * METERS_PER_MILE),
+ Math.round(0.5 * METERS_PER_MILE),
+ Math.round(1 * METERS_PER_MILE),
+ Math.round(5 * METERS_PER_MILE),
+ Math.round(10 * METERS_PER_MILE),
+];
+
+interface WaypointEditDialogProps {
+ open: boolean;
+ onOpenChange: (open: boolean) => void;
+ waypoint: WaypointWithMetadata | undefined;
+ initialLngLat: LngLat | undefined;
+ channel: number;
+ mapRef: MapRef | undefined;
+ onRequestBoundingBoxDraw: () => Promise<
+ { west: number; south: number; east: number; north: number } | undefined
+ >;
+}
+
+interface FormState {
+ name: string;
+ description: string;
+ icon: string;
+ latitude: string;
+ longitude: string;
+ expireEnabled: boolean;
+ expireIso: string;
+ radiusValue: string;
+ useLargeUnit: boolean;
+ west: string;
+ south: string;
+ east: string;
+ north: string;
+ hasBox: boolean;
+ notifyOnEnter: boolean;
+ notifyOnExit: boolean;
+ notifyFavoritesOnly: boolean;
+}
+
+function isoLocal(epochSeconds: number): string {
+ const d = new Date(epochSeconds * 1000);
+ const pad = (n: number) => String(n).padStart(2, "0");
+ return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;
+}
+
+function initialForm(
+ wp: WaypointWithMetadata | undefined,
+ initialLngLat: LngLat | undefined,
+ system: "metric" | "imperial",
+): FormState {
+ if (wp) {
+ const box = wp.boundingBox;
+ const radiusMeters = wp.geofenceRadius ?? 0;
+ const useLargeUnit =
+ system === "imperial"
+ ? radiusMeters >= IMPERIAL_MILES_THRESHOLD_METERS
+ : radiusMeters >= 1000;
+ const displayed =
+ radiusMeters > 0 ? metersToDisplay(radiusMeters, system) : 0;
+ return {
+ name: wp.name,
+ description: wp.description,
+ icon: String.fromCodePoint(wp.icon || DEFAULT_ICON_CODEPOINT),
+ latitude: String(coordToDeg(wp.latitudeI)),
+ longitude: String(coordToDeg(wp.longitudeI)),
+ expireEnabled: wp.expire !== 0,
+ expireIso: wp.expire !== 0 ? isoLocal(wp.expire) : "",
+ radiusValue: radiusMeters > 0 ? String(Number(displayed.toFixed(2))) : "",
+ useLargeUnit,
+ hasBox: Boolean(box),
+ west: box ? String(coordToDeg(box.longitudeWestI)) : "",
+ south: box ? String(coordToDeg(box.latitudeSouthI)) : "",
+ east: box ? String(coordToDeg(box.longitudeEastI)) : "",
+ north: box ? String(coordToDeg(box.latitudeNorthI)) : "",
+ notifyOnEnter: wp.notifyOnEnter,
+ notifyOnExit: wp.notifyOnExit,
+ notifyFavoritesOnly: wp.notifyFavoritesOnly,
+ };
+ }
+
+ const [lng, lat] = initialLngLat ?? [0, 0];
+ return {
+ name: "",
+ description: "",
+ icon: String.fromCodePoint(DEFAULT_ICON_CODEPOINT),
+ latitude: String(lat),
+ longitude: String(lng),
+ expireEnabled: false,
+ expireIso: "",
+ radiusValue: "",
+ useLargeUnit: false,
+ hasBox: false,
+ west: "",
+ south: "",
+ east: "",
+ north: "",
+ notifyOnEnter: false,
+ notifyOnExit: false,
+ notifyFavoritesOnly: false,
+ };
+}
+
+function parseIcon(input: string): number {
+ const trimmed = input.trim();
+ if (!trimmed) return DEFAULT_ICON_CODEPOINT;
+ return trimmed.codePointAt(0) ?? DEFAULT_ICON_CODEPOINT;
+}
+
+export const WaypointEditDialog = ({
+ open,
+ onOpenChange,
+ waypoint,
+ initialLngLat,
+ channel,
+ mapRef,
+ onRequestBoundingBoxDraw,
+}: WaypointEditDialogProps) => {
+ const { t } = useTranslation("map");
+ const { toast } = useToast();
+ const device = useDevice();
+ const displayUnits = device.config.display?.units;
+ const unitSystem = useMemo(
+ () => unitSystemFromDisplayUnits(displayUnits),
+ [displayUnits],
+ );
+ const [form, setForm] = useState(() =>
+ initialForm(waypoint, initialLngLat, unitSystem),
+ );
+ const [saving, setSaving] = useState(false);
+ const isCreating = waypoint === undefined;
+
+ useEffect(() => {
+ setForm(initialForm(waypoint, initialLngLat, unitSystem));
+ }, [waypoint, initialLngLat, unitSystem]);
+
+ const currentRadiusMeters = useMemo(() => {
+ const parsed = Number.parseFloat(form.radiusValue);
+ if (!Number.isFinite(parsed) || parsed <= 0) return 0;
+ return Math.round(displayToMeters(parsed, unitSystem, form.useLargeUnit));
+ }, [form.radiusValue, form.useLargeUnit, unitSystem]);
+
+ const radiusPresets =
+ unitSystem === "imperial"
+ ? IMPERIAL_RADIUS_PRESETS_M
+ : METRIC_RADIUS_PRESETS_M;
+
+ const applyRadiusPreset = useCallback(
+ (meters: number) => {
+ if (meters === 0) {
+ setForm((s) => ({ ...s, radiusValue: "", useLargeUnit: false }));
+ return;
+ }
+ const useLargeUnit =
+ unitSystem === "imperial"
+ ? meters >= IMPERIAL_MILES_THRESHOLD_METERS
+ : meters >= 1000;
+ const displayed = metersToDisplay(meters, unitSystem);
+ setForm((s) => ({
+ ...s,
+ radiusValue: String(Number(displayed.toFixed(2))),
+ useLargeUnit,
+ }));
+ },
+ [unitSystem],
+ );
+
+ const requestDraw = useCallback(async () => {
+ const box = await onRequestBoundingBoxDraw();
+ if (!box) return;
+ setForm((s) => ({
+ ...s,
+ hasBox: true,
+ west: box.west.toFixed(6),
+ south: box.south.toFixed(6),
+ east: box.east.toFixed(6),
+ north: box.north.toFixed(6),
+ }));
+ }, [onRequestBoundingBoxDraw]);
+
+ const hasAnyGeofence = currentRadiusMeters > 0 || form.hasBox;
+ const hasAnyNotifyOn = form.notifyOnEnter || form.notifyOnExit;
+
+ const boxSummary = form.hasBox
+ ? `${Number(form.south).toFixed(3)}, ${Number(form.west).toFixed(3)} → ${Number(form.north).toFixed(3)}, ${Number(form.east).toFixed(3)}`
+ : "";
+
+ const handleSave = useCallback(async () => {
+ setSaving(true);
+ try {
+ const base: Protobuf.Mesh.Waypoint = waypoint
+ ? clone(Protobuf.Mesh.WaypointSchema, waypoint)
+ : create(Protobuf.Mesh.WaypointSchema, {});
+
+ const trimmedName = form.name.trim().slice(0, WAYPOINT_NAME_MAX);
+ if (!trimmedName) {
+ toast({ title: t("waypointEdit.errorMissingName") });
+ return;
+ }
+ base.name = trimmedName;
+ base.description = form.description.slice(0, WAYPOINT_DESC_MAX);
+ base.icon = parseIcon(form.icon);
+
+ const lat = Number.parseFloat(form.latitude);
+ const lng = Number.parseFloat(form.longitude);
+ if (!Number.isFinite(lat) || !Number.isFinite(lng)) {
+ toast({ title: t("waypointEdit.errorBadCoords") });
+ setSaving(false);
+ return;
+ }
+ base.latitudeI = degToCoordI(lat);
+ base.longitudeI = degToCoordI(lng);
+
+ if (form.expireEnabled && form.expireIso) {
+ const epoch = Math.floor(new Date(form.expireIso).getTime() / 1000);
+ base.expire = Number.isFinite(epoch) && epoch > 0 ? epoch : 0;
+ } else {
+ base.expire = 0;
+ }
+
+ const parsedRadius = Number.parseFloat(form.radiusValue);
+ base.geofenceRadius =
+ Number.isFinite(parsedRadius) && parsedRadius > 0
+ ? Math.round(
+ displayToMeters(parsedRadius, unitSystem, form.useLargeUnit),
+ )
+ : 0;
+
+ if (form.hasBox) {
+ const [west, south, east, north] = [
+ form.west,
+ form.south,
+ form.east,
+ form.north,
+ ].map((v) => Number.parseFloat(v));
+ if ([west, south, east, north].every((n) => Number.isFinite(n))) {
+ base.boundingBox = create(Protobuf.Mesh.BoundingBoxSchema, {
+ longitudeWestI: degToCoordI(west!),
+ latitudeSouthI: degToCoordI(south!),
+ longitudeEastI: degToCoordI(east!),
+ latitudeNorthI: degToCoordI(north!),
+ });
+ }
+ } else {
+ base.boundingBox = undefined;
+ }
+ base.notifyOnEnter = hasAnyGeofence && form.notifyOnEnter;
+ base.notifyOnExit = hasAnyGeofence && form.notifyOnExit;
+ base.notifyFavoritesOnly = hasAnyGeofence && form.notifyFavoritesOnly;
+
+ if (isCreating && base.id === 0) {
+ // Reuse the SDK's CSPRNG packet-id generator so the local id we
+ // store matches the id `sendWaypoint` will broadcast — otherwise
+ // `addWaypoint`'s per-id dedup can collide with an existing entry.
+ base.id = generatePacketId();
+ }
+
+ const targetChannel = waypoint?.metadata.channel ?? channel;
+ const fromNode = waypoint?.metadata.from ?? device.hardware.myNodeNum;
+ if (device.connection) {
+ await device.connection.sendWaypoint(base, "broadcast", targetChannel);
+ }
+ device.addWaypoint(base, targetChannel, fromNode, new Date());
+ toast({
+ title: isCreating
+ ? t("waypointEdit.createdToast", { name: base.name })
+ : t("waypointEdit.savedToast", { name: base.name }),
+ });
+ onOpenChange(false);
+ } catch (err) {
+ toast({
+ title: t("waypointEdit.errorToast"),
+ description: err instanceof Error ? err.message : String(err),
+ });
+ } finally {
+ setSaving(false);
+ }
+ }, [
+ channel,
+ device,
+ form,
+ isCreating,
+ onOpenChange,
+ t,
+ toast,
+ unitSystem,
+ waypoint,
+ ]);
+
+ return (
+
+ );
+};
diff --git a/apps/web/src/components/PageComponents/Map/BoundingBoxOverlay.tsx b/apps/web/src/components/PageComponents/Map/BoundingBoxOverlay.tsx
new file mode 100644
index 000000000..bdb3a231f
--- /dev/null
+++ b/apps/web/src/components/PageComponents/Map/BoundingBoxOverlay.tsx
@@ -0,0 +1,25 @@
+import type { MapRef } from "react-map-gl/maplibre";
+
+interface BoundingBoxOverlayProps {
+ mapRef: MapRef;
+ start: [number, number];
+ current: [number, number];
+}
+
+export const BoundingBoxOverlay = ({ mapRef, start, current }: BoundingBoxOverlayProps) => {
+ const map = mapRef.getMap();
+ if (!map) return null;
+ const rect = map.getContainer().getBoundingClientRect();
+ const a = map.project(start);
+ const b = map.project(current);
+ const left = Math.min(a.x, b.x) + rect.left;
+ const top = Math.min(a.y, b.y) + rect.top;
+ const width = Math.abs(a.x - b.x);
+ const height = Math.abs(a.y - b.y);
+ return (
+
+ );
+};
diff --git a/apps/web/src/components/PageComponents/Map/Layers/GeofenceLayer.test.ts b/apps/web/src/components/PageComponents/Map/Layers/GeofenceLayer.test.ts
new file mode 100644
index 000000000..d7fd3d5ca
--- /dev/null
+++ b/apps/web/src/components/PageComponents/Map/Layers/GeofenceLayer.test.ts
@@ -0,0 +1,62 @@
+import { create } from "@bufbuild/protobuf";
+import { Protobuf } from "@meshtastic/sdk";
+import { describe, expect, it } from "vitest";
+import { generateGeofenceFeatures } from "./GeofenceLayer.tsx";
+
+function makeWaypoint(fields: Record) {
+ const wp = create(Protobuf.Mesh.WaypointSchema, fields as never);
+ return Object.assign(wp, {
+ metadata: { channel: 0, created: new Date(), from: 1 },
+ });
+}
+
+describe("GeofenceLayer – feature generation", () => {
+ it("skips waypoints without a geofence", () => {
+ const fc = generateGeofenceFeatures([makeWaypoint({ id: 1 })]);
+ expect(fc.features).toHaveLength(0);
+ });
+
+ it("emits a circle polygon for radius > 0", () => {
+ const fc = generateGeofenceFeatures([
+ makeWaypoint({ id: 1, latitudeI: 400000000, longitudeI: -740000000, geofenceRadius: 500 }),
+ ]);
+ expect(fc.features).toHaveLength(1);
+ expect(fc.features[0]!.properties.kind).toBe("circle");
+ expect(fc.features[0]!.properties.waypointId).toBe(1);
+ });
+
+ it("emits a rectangle polygon for bounding box", () => {
+ const box = create(Protobuf.Mesh.BoundingBoxSchema, {
+ longitudeWestI: -740100000,
+ latitudeSouthI: 399900000,
+ longitudeEastI: -739900000,
+ latitudeNorthI: 400100000,
+ });
+ const fc = generateGeofenceFeatures([makeWaypoint({ id: 2, boundingBox: box })]);
+ expect(fc.features).toHaveLength(1);
+ expect(fc.features[0]!.properties.kind).toBe("box");
+ const ring = fc.features[0]!.geometry.coordinates[0]!;
+ expect(ring).toHaveLength(5);
+ expect(ring[0]).toEqual(ring[4]);
+ });
+
+ it("emits both shapes when both are set", () => {
+ const box = create(Protobuf.Mesh.BoundingBoxSchema, {
+ longitudeWestI: 0,
+ latitudeSouthI: 0,
+ longitudeEastI: 1000000,
+ latitudeNorthI: 1000000,
+ });
+ const fc = generateGeofenceFeatures([
+ makeWaypoint({
+ id: 3,
+ latitudeI: 0,
+ longitudeI: 0,
+ geofenceRadius: 100,
+ boundingBox: box,
+ }),
+ ]);
+ expect(fc.features).toHaveLength(2);
+ expect(fc.features.map((f) => f.properties.kind).sort()).toEqual(["box", "circle"]);
+ });
+});
diff --git a/apps/web/src/components/PageComponents/Map/Layers/GeofenceLayer.tsx b/apps/web/src/components/PageComponents/Map/Layers/GeofenceLayer.tsx
new file mode 100644
index 000000000..855a01bbb
--- /dev/null
+++ b/apps/web/src/components/PageComponents/Map/Layers/GeofenceLayer.tsx
@@ -0,0 +1,102 @@
+import type { WaypointWithMetadata } from "@core/stores";
+import { toLngLat } from "@core/utils/geo.ts";
+import { coordToDeg, hasGeofence } from "@core/utils/geofence.ts";
+import { circle } from "@turf/turf";
+import type { Feature, FeatureCollection, Polygon } from "geojson";
+import { useMemo } from "react";
+import { Layer, Source } from "react-map-gl/maplibre";
+
+export interface GeofenceLayerProps {
+ id: string;
+ waypoints: readonly WaypointWithMetadata[];
+ isVisible: boolean;
+}
+
+type FeatureProps = {
+ waypointId: number;
+ kind: "circle" | "box";
+};
+
+export function generateGeofenceFeatures(
+ waypoints: readonly WaypointWithMetadata[],
+): FeatureCollection {
+ const features: Feature[] = [];
+ for (const wp of waypoints) {
+ if (!hasGeofence(wp)) continue;
+ if (wp.geofenceRadius > 0) {
+ const [lng, lat] = toLngLat({
+ latitudeI: wp.latitudeI,
+ longitudeI: wp.longitudeI,
+ });
+ const feat = circle([lng, lat], wp.geofenceRadius, {
+ steps: 64,
+ units: "meters",
+ }) as Feature;
+ feat.properties = { waypointId: wp.id, kind: "circle" };
+ features.push(feat);
+ }
+ if (wp.boundingBox) {
+ const west = coordToDeg(wp.boundingBox.longitudeWestI);
+ const east = coordToDeg(wp.boundingBox.longitudeEastI);
+ const south = coordToDeg(wp.boundingBox.latitudeSouthI);
+ const north = coordToDeg(wp.boundingBox.latitudeNorthI);
+ const rectangle = (w: number, e: number): Polygon => ({
+ type: "Polygon",
+ coordinates: [
+ [
+ [w, south],
+ [e, south],
+ [e, north],
+ [w, north],
+ [w, south],
+ ],
+ ],
+ });
+ // Anti-meridian: split into two polygons so we don't render a
+ // huge polygon wrapping around the globe.
+ const geometries =
+ west <= east
+ ? [rectangle(west, east)]
+ : [rectangle(west, 180), rectangle(-180, east)];
+ for (const geometry of geometries) {
+ features.push({
+ type: "Feature",
+ properties: { waypointId: wp.id, kind: "box" },
+ geometry,
+ });
+ }
+ }
+ }
+ return { type: "FeatureCollection", features };
+}
+
+export const GeofenceLayer = ({
+ id,
+ waypoints,
+ isVisible,
+}: GeofenceLayerProps) => {
+ const data = useMemo(() => generateGeofenceFeatures(waypoints), [waypoints]);
+ return (
+
+
+
+
+ );
+};
diff --git a/apps/web/src/components/PageComponents/Map/Layers/WaypointLayer.tsx b/apps/web/src/components/PageComponents/Map/Layers/WaypointLayer.tsx
index 429bb1ef2..b48668453 100644
--- a/apps/web/src/components/PageComponents/Map/Layers/WaypointLayer.tsx
+++ b/apps/web/src/components/PageComponents/Map/Layers/WaypointLayer.tsx
@@ -14,6 +14,7 @@ export interface WaypointLayerProps {
isVisible: boolean;
popupState: PopupState | undefined;
setPopupState: (state: PopupState | undefined) => void;
+ onEditWaypoint: (waypoint: WaypointWithMetadata) => void;
}
import { toLngLat } from "@core/utils/geo.ts";
@@ -24,6 +25,7 @@ export const WaypointLayer = ({
isVisible,
popupState,
setPopupState,
+ onEditWaypoint,
}: WaypointLayerProps): React.ReactNode[] => {
const { waypoints } = useDevice();
const { focusLngLat } = useMapFitting(mapRef);
@@ -85,10 +87,11 @@ export const WaypointLayer = ({
{}}
+ onEdit={() => onEditWaypoint(popupState.waypoint)}
/>
,
);
}
+
return rendered;
};
diff --git a/apps/web/src/components/PageComponents/Map/Popups/WaypointDetail.tsx b/apps/web/src/components/PageComponents/Map/Popups/WaypointDetail.tsx
index b938d39f3..31e899161 100644
--- a/apps/web/src/components/PageComponents/Map/Popups/WaypointDetail.tsx
+++ b/apps/web/src/components/PageComponents/Map/Popups/WaypointDetail.tsx
@@ -1,4 +1,5 @@
import { TimeAgo } from "@components/generic/TimeAgo";
+import { Button } from "@components/UI/Button.tsx";
import { Separator } from "@components/UI/Separator.tsx";
import { useNodeAsProto } from "@core/hooks/useNodesAsProto.ts";
import type { WaypointWithMetadata } from "@core/stores";
@@ -8,15 +9,19 @@ import {
hasPos,
toLngLat,
} from "@core/utils/geo";
+import { hasGeofence } from "@core/utils/geofence.ts";
import type { Protobuf } from "@meshtastic/sdk";
import {
+ BellIcon,
ClockFadingIcon,
ClockPlusIcon,
CompassIcon,
MapPinnedIcon,
MoveHorizontalIcon,
NavigationIcon,
+ PencilIcon,
RotateCwIcon,
+ ShieldIcon,
UserLockIcon,
} from "lucide-react";
import { useTranslation } from "react-i18next";
@@ -27,7 +32,7 @@ interface WaypointDetailProps {
onEdit: () => void;
}
-export const WaypointDetail = ({ waypoint, myNode }: WaypointDetailProps) => {
+export const WaypointDetail = ({ waypoint, myNode, onEdit }: WaypointDetailProps) => {
const { t } = useTranslation("map");
const lockedToNode = useNodeAsProto(waypoint.lockedTo ?? 0);
@@ -183,8 +188,50 @@ export const WaypointDetail = ({ waypoint, myNode }: WaypointDetailProps) => {
)}
+
+ {/* Geofence radius */}
+ {waypoint.geofenceRadius > 0 && (
+
+
+
+ {t("waypointDetail.geofenceRadius")}
+
+
+ {waypoint.geofenceRadius}{" "}
+ {waypoint.geofenceRadius === 1 ? t("unit.meter.one") : t("unit.meter.plural")}
+
+
+ )}
+
+ {/* Alert flags */}
+ {(waypoint.notifyOnEnter || waypoint.notifyOnExit) && (
+
+
+
+ {t("waypointDetail.notifications")}
+
+
+ {[
+ waypoint.notifyOnEnter ? t("waypointDetail.enter") : undefined,
+ waypoint.notifyOnExit ? t("waypointDetail.exit") : undefined,
+ waypoint.notifyFavoritesOnly ? t("waypointDetail.favoritesOnly") : undefined,
+ ]
+ .filter(Boolean)
+ .join(" · ")}
+
+
+ )}
+
+
);
};
diff --git a/apps/web/src/components/PageComponents/Map/Tools/MapLayerTool.tsx b/apps/web/src/components/PageComponents/Map/Tools/MapLayerTool.tsx
index 3b9b1cef7..4b422d086 100644
--- a/apps/web/src/components/PageComponents/Map/Tools/MapLayerTool.tsx
+++ b/apps/web/src/components/PageComponents/Map/Tools/MapLayerTool.tsx
@@ -17,6 +17,7 @@ export interface VisibilityState {
positionPrecision: boolean;
traceroutes: boolean;
waypoints: boolean;
+ geofences: boolean;
heatmap: boolean;
}
@@ -27,6 +28,7 @@ export const defaultVisibilityState: VisibilityState = {
positionPrecision: false,
traceroutes: false,
waypoints: true,
+ geofences: true,
heatmap: false,
};
@@ -83,6 +85,7 @@ export function MapLayerTool({
positionPrecision: false,
traceroutes: false,
waypoints: false,
+ geofences: false,
heatmap: true,
});
} else {
@@ -97,6 +100,7 @@ export function MapLayerTool({
() => [
{ key: "nodeMarkers", label: t("layerTool.nodeMarkers") },
{ key: "waypoints", label: t("layerTool.waypoints") },
+ { key: "geofences", label: t("layerTool.geofences") },
{ key: "directNeighbors", label: t("layerTool.directNeighbors") },
{ key: "remoteNeighbors", label: t("layerTool.remoteNeighbors") },
{ key: "positionPrecision", label: t("layerTool.positionPrecision") },
diff --git a/apps/web/src/core/hooks/useBoundingBoxDraw.test.tsx b/apps/web/src/core/hooks/useBoundingBoxDraw.test.tsx
new file mode 100644
index 000000000..38f2d742a
--- /dev/null
+++ b/apps/web/src/core/hooks/useBoundingBoxDraw.test.tsx
@@ -0,0 +1,104 @@
+import { act, renderHook } from "@testing-library/react";
+import { describe, expect, it, vi } from "vitest";
+import { useBoundingBoxDraw } from "./useBoundingBoxDraw.ts";
+
+function makeMapRef(unprojectFn: (pt: [number, number]) => { lng: number; lat: number }) {
+ const container = {
+ getBoundingClientRect: () => ({ left: 0, top: 0 }) as DOMRect,
+ } as HTMLElement;
+ const map = {
+ unproject: vi.fn(unprojectFn),
+ getContainer: () => container,
+ };
+ return {
+ getMap: () => map,
+ } as unknown as Parameters[0];
+}
+
+function makePointerEvent(x: number, y: number, pointerId = 1): React.PointerEvent {
+ const target = {
+ setPointerCapture: vi.fn(),
+ releasePointerCapture: vi.fn(),
+ hasPointerCapture: vi.fn().mockReturnValue(true),
+ };
+ return {
+ clientX: x,
+ clientY: y,
+ pointerId,
+ currentTarget: target,
+ } as unknown as React.PointerEvent;
+}
+
+describe("useBoundingBoxDraw", () => {
+ it("returns undefined without a map", async () => {
+ const { result } = renderHook(() => useBoundingBoxDraw(undefined));
+ let value: unknown;
+ await act(async () => {
+ const promise = result.current.beginDraw();
+ result.current.cancelDraw();
+ value = await promise;
+ });
+ expect(value).toBeUndefined();
+ expect(result.current.active).toBe(false);
+ });
+
+ it("resolves with normalized WSEN box after drag", async () => {
+ const mapRef = makeMapRef(([x, y]) => ({ lng: x / 10, lat: y / 10 }));
+ const { result } = renderHook(() => useBoundingBoxDraw(mapRef));
+
+ let promise: Promise;
+ act(() => {
+ promise = result.current.beginDraw();
+ });
+ expect(result.current.active).toBe(true);
+
+ act(() => {
+ result.current.onPointerDown(makePointerEvent(100, 200));
+ });
+ act(() => {
+ result.current.onPointerMove(makePointerEvent(300, 50));
+ });
+ act(() => {
+ result.current.onPointerUp(makePointerEvent(300, 50));
+ });
+
+ const box = (await promise!) as { west: number; south: number; east: number; north: number };
+ expect(box.west).toBe(10);
+ expect(box.east).toBe(30);
+ expect(box.south).toBe(5);
+ expect(box.north).toBe(20);
+ expect(result.current.active).toBe(false);
+ });
+
+ it("resolves undefined on zero-area drag", async () => {
+ const mapRef = makeMapRef(([x, y]) => ({ lng: x, lat: y }));
+ const { result } = renderHook(() => useBoundingBoxDraw(mapRef));
+ let promise: Promise;
+ act(() => {
+ promise = result.current.beginDraw();
+ });
+ act(() => {
+ result.current.onPointerDown(makePointerEvent(50, 50));
+ });
+ act(() => {
+ result.current.onPointerUp(makePointerEvent(50, 50));
+ });
+ const box = await promise!;
+ expect(box).toBeUndefined();
+ });
+
+ it("cancelDraw resolves outstanding promise as undefined", async () => {
+ const mapRef = makeMapRef(([x, y]) => ({ lng: x, lat: y }));
+ const { result } = renderHook(() => useBoundingBoxDraw(mapRef));
+ let promise: Promise;
+ act(() => {
+ promise = result.current.beginDraw();
+ });
+ act(() => {
+ result.current.cancelDraw();
+ });
+ const box = await promise!;
+ expect(box).toBeUndefined();
+ expect(result.current.active).toBe(false);
+ });
+});
diff --git a/apps/web/src/core/hooks/useBoundingBoxDraw.ts b/apps/web/src/core/hooks/useBoundingBoxDraw.ts
new file mode 100644
index 000000000..180812a79
--- /dev/null
+++ b/apps/web/src/core/hooks/useBoundingBoxDraw.ts
@@ -0,0 +1,113 @@
+import { useCallback, useRef, useState } from "react";
+import type { MapRef } from "react-map-gl/maplibre";
+
+export type BoundingBoxResult = {
+ west: number;
+ south: number;
+ east: number;
+ north: number;
+};
+
+interface DrawState {
+ active: boolean;
+ start?: [number, number];
+ current?: [number, number];
+}
+
+/**
+ * Drag-to-define rectangular selector on a MapLibre map. Returns a state
+ * object plus a `beginDraw` promise-based API for callers (the editor
+ * dialog) to await a result. Matches design#114 "Set / Edit / Remove
+ * Bounding Box opens a drag-to-define rectangle on the map."
+ */
+export function useBoundingBoxDraw(mapRef: MapRef | undefined) {
+ const [state, setState] = useState({ active: false });
+ const startRef = useRef<[number, number] | undefined>(undefined);
+ const currentRef = useRef<[number, number] | undefined>(undefined);
+ const resolverRef = useRef<((box: BoundingBoxResult | undefined) => void) | undefined>(undefined);
+
+ const beginDraw = useCallback((): Promise => {
+ return new Promise((resolve) => {
+ resolverRef.current?.(undefined);
+ resolverRef.current = resolve;
+ startRef.current = undefined;
+ currentRef.current = undefined;
+ setState({ active: true });
+ });
+ }, []);
+
+ const cancelDraw = useCallback(() => {
+ resolverRef.current?.(undefined);
+ resolverRef.current = undefined;
+ startRef.current = undefined;
+ currentRef.current = undefined;
+ setState({ active: false });
+ }, []);
+
+ const onPointerDown = useCallback(
+ (event: React.PointerEvent) => {
+ const map = mapRef?.getMap();
+ if (!map) return;
+ const rect = map.getContainer().getBoundingClientRect();
+ const lngLat = map.unproject([event.clientX - rect.left, event.clientY - rect.top]);
+ startRef.current = [lngLat.lng, lngLat.lat];
+ currentRef.current = [lngLat.lng, lngLat.lat];
+ setState({ active: true, start: startRef.current, current: currentRef.current });
+ event.currentTarget.setPointerCapture(event.pointerId);
+ },
+ [mapRef],
+ );
+
+ const onPointerMove = useCallback(
+ (event: React.PointerEvent) => {
+ if (!startRef.current) return;
+ const map = mapRef?.getMap();
+ if (!map) return;
+ const rect = map.getContainer().getBoundingClientRect();
+ const lngLat = map.unproject([event.clientX - rect.left, event.clientY - rect.top]);
+ currentRef.current = [lngLat.lng, lngLat.lat];
+ setState((s) => ({ ...s, current: currentRef.current }));
+ },
+ [mapRef],
+ );
+
+ const onPointerUp = useCallback((event: React.PointerEvent) => {
+ let box: BoundingBoxResult | undefined;
+ if (startRef.current && currentRef.current) {
+ const [x1, y1] = startRef.current;
+ const [x2, y2] = currentRef.current;
+ const west = Math.min(x1, x2);
+ const east = Math.max(x1, x2);
+ const south = Math.min(y1, y2);
+ const north = Math.max(y1, y2);
+ if (Math.abs(east - west) > 1e-6 && Math.abs(north - south) > 1e-6) {
+ box = { west, south, east, north };
+ }
+ }
+ startRef.current = undefined;
+ currentRef.current = undefined;
+ setState({ active: false });
+ if (event.currentTarget.hasPointerCapture(event.pointerId)) {
+ event.currentTarget.releasePointerCapture(event.pointerId);
+ }
+ resolverRef.current?.(box);
+ resolverRef.current = undefined;
+ }, []);
+
+ const overlay = state.active
+ ? {
+ start: state.start,
+ current: state.current,
+ }
+ : undefined;
+
+ return {
+ active: state.active,
+ overlay,
+ beginDraw,
+ cancelDraw,
+ onPointerDown,
+ onPointerMove,
+ onPointerUp,
+ };
+}
diff --git a/apps/web/src/core/hooks/useGeofenceAlerts.ts b/apps/web/src/core/hooks/useGeofenceAlerts.ts
new file mode 100644
index 000000000..636194895
--- /dev/null
+++ b/apps/web/src/core/hooks/useGeofenceAlerts.ts
@@ -0,0 +1,73 @@
+import { router } from "@app/routes.tsx";
+import { ToastAction, type ToastActionElement } from "@components/UI/Toast.tsx";
+import { toast } from "@core/hooks/useToast.ts";
+import { useAppStore, useDevice } from "@core/stores";
+import { GeofenceCrossings } from "@core/utils/geofenceCrossings.ts";
+import { useActiveClient } from "@meshtastic/sdk-react";
+import { createElement, useEffect, useRef } from "react";
+import { useTranslation } from "react-i18next";
+
+/**
+ * Evaluates every incoming node position against every waypoint with a
+ * geofence and any notify flag set. First sighting for a
+ * `(waypointId, nodeNum)` pair only records a baseline (per design#114) —
+ * subsequent transitions fire an enter/exit toast, gated by
+ * `notify_favorites_only`. Toast carries an action that navigates to the
+ * Map page and focuses the waypoint (design#114 "Notification action:
+ * deep-link to the waypoint on the map").
+ */
+export function useGeofenceAlerts() {
+ const client = useActiveClient();
+ const device = useDevice();
+ const setFocusWaypointId = useAppStore((s) => s.setFocusWaypointId);
+ const { t } = useTranslation("map");
+ const crossings = useRef(new GeofenceCrossings()).current;
+ const waypointsRef = useRef(device.waypoints);
+ waypointsRef.current = device.waypoints;
+
+ useEffect(() => {
+ if (!client) return;
+
+ const dispose = client.events.onPositionPacket.subscribe((packet) => {
+ const { from, data } = packet;
+ if (data.latitudeI == null || data.longitudeI == null) return;
+ const point: [number, number] = [data.longitudeI / 1e7, data.latitudeI / 1e7];
+ const waypoints = waypointsRef.current;
+ const events = crossings.evaluate(point, from, waypoints);
+ if (events.length === 0) return;
+
+ for (const event of events) {
+ const wp = waypoints.find((w) => w.id === event.waypointId);
+ if (!wp) continue;
+ if (wp.notifyFavoritesOnly) {
+ const node = client.nodes.byNum(from);
+ if (!node?.isFavorite) continue;
+ }
+ const node = client.nodes.byNum(from);
+ const nodeName = node?.user?.longName ?? String(from);
+ toast({
+ title:
+ event.kind === "enter"
+ ? t("waypointEdit.enterToast", { node: nodeName, waypoint: wp.name })
+ : t("waypointEdit.exitToast", { node: nodeName, waypoint: wp.name }),
+ action: createElement(
+ ToastAction,
+ {
+ altText: t("waypointEdit.viewOnMap"),
+ onClick: () => {
+ setFocusWaypointId(wp.id);
+ void router.navigate({ to: "/map" });
+ },
+ },
+ t("waypointEdit.viewOnMap"),
+ ) as unknown as ToastActionElement,
+ });
+ }
+ });
+
+ return () => {
+ dispose();
+ crossings.reset();
+ };
+ }, [client, crossings, setFocusWaypointId, t]);
+}
diff --git a/apps/web/src/core/stores/appStore/appStore.test.ts b/apps/web/src/core/stores/appStore/appStore.test.ts
index 7ebe8ca0e..8f58e1611 100644
--- a/apps/web/src/core/stores/appStore/appStore.test.ts
+++ b/apps/web/src/core/stores/appStore/appStore.test.ts
@@ -65,6 +65,12 @@ describe("AppStore – basic state & actions", () => {
state.setNodeNumDetails(777);
expect(useAppStore.getState().nodeNumDetails).toBe(777);
+
+ expect(useAppStore.getState().focusWaypointId).toBeUndefined();
+ state.setFocusWaypointId(555);
+ expect(useAppStore.getState().focusWaypointId).toBe(555);
+ state.setFocusWaypointId(undefined);
+ expect(useAppStore.getState().focusWaypointId).toBeUndefined();
});
it("setRasterSources replaces; addRasterSource appends; removeRasterSource splices by index", async () => {
diff --git a/apps/web/src/core/stores/appStore/index.ts b/apps/web/src/core/stores/appStore/index.ts
index 72034911d..7c4738074 100644
--- a/apps/web/src/core/stores/appStore/index.ts
+++ b/apps/web/src/core/stores/appStore/index.ts
@@ -24,6 +24,7 @@ export interface AppState extends AppData {
connectDialogOpen: boolean;
nodeNumDetails: number;
commandPaletteOpen: boolean;
+ focusWaypointId: number | undefined;
setRasterSources: (sources: RasterSource[]) => void;
addRasterSource: (source: RasterSource) => void;
@@ -33,6 +34,7 @@ export interface AppState extends AppData {
setNodeNumToBeRemoved: (nodeNum: number) => void;
setConnectDialogOpen: (open: boolean) => void;
setNodeNumDetails: (nodeNum: number) => void;
+ setFocusWaypointId: (id: number | undefined) => void;
}
export const deviceStoreInitializer: StateCreator = (set, _get) => ({
@@ -42,6 +44,7 @@ export const deviceStoreInitializer: StateCreator = (set, _get) => ({
connectDialogOpen: false,
nodeNumToBeRemoved: 0,
nodeNumDetails: 0,
+ focusWaypointId: undefined,
setRasterSources: (sources: RasterSource[]) => {
set(
@@ -90,6 +93,10 @@ export const deviceStoreInitializer: StateCreator = (set, _get) => ({
set(() => ({
nodeNumDetails: nodeNum,
})),
+ setFocusWaypointId: (id) =>
+ set(() => ({
+ focusWaypointId: id,
+ })),
});
const persistOptions: PersistOptions = {
diff --git a/apps/web/src/core/stores/deviceStore/deviceStore.test.ts b/apps/web/src/core/stores/deviceStore/deviceStore.test.ts
index b473e141d..13c5d5689 100644
--- a/apps/web/src/core/stores/deviceStore/deviceStore.test.ts
+++ b/apps/web/src/core/stores/deviceStore/deviceStore.test.ts
@@ -49,6 +49,24 @@ function makeWaypoint(id: number, expire?: number) {
return create(Protobuf.Mesh.WaypointSchema, { id, expire });
}
+function makeGeofenceWaypoint(id: number) {
+ return create(Protobuf.Mesh.WaypointSchema, {
+ id,
+ latitudeI: 400000000,
+ longitudeI: -740000000,
+ geofenceRadius: 250,
+ boundingBox: create(Protobuf.Mesh.BoundingBoxSchema, {
+ longitudeWestI: -740100000,
+ latitudeSouthI: 399900000,
+ longitudeEastI: -739900000,
+ latitudeNorthI: 400100000,
+ }),
+ notifyOnEnter: true,
+ notifyOnExit: false,
+ notifyFavoritesOnly: true,
+ });
+}
+
function makeAdminMessage(fields: Record) {
return create(Protobuf.Admin.AdminMessageSchema, fields);
}
@@ -254,6 +272,31 @@ describe("DeviceStore – traceroutes & waypoints retention + merge on setHardwa
});
});
+describe("DeviceStore – geofence field persistence", () => {
+ beforeEach(() => {
+ idbMem.clear();
+ vi.clearAllMocks();
+ });
+
+ it("addWaypoint carries geofence fields through the store", async () => {
+ const { useDeviceStore } = await freshStore(false);
+ const state = useDeviceStore.getState();
+ const device = state.addDevice(1);
+ device.addWaypoint(makeGeofenceWaypoint(42), 0, 5, new Date());
+
+ const stored = useDeviceStore
+ .getState()
+ .devices.get(1)!
+ .waypoints.find((w) => w.id === 42)!;
+ expect(stored.geofenceRadius).toBe(250);
+ expect(stored.notifyOnEnter).toBe(true);
+ expect(stored.notifyOnExit).toBe(false);
+ expect(stored.notifyFavoritesOnly).toBe(true);
+ expect(stored.boundingBox?.latitudeNorthI).toBe(400100000);
+ expect(stored.boundingBox?.longitudeWestI).toBe(-740100000);
+ });
+});
+
describe("DeviceStore – persistence partialize & rehydrate", () => {
beforeEach(() => {
idbMem.clear();
diff --git a/apps/web/src/core/utils/geofence.test.ts b/apps/web/src/core/utils/geofence.test.ts
new file mode 100644
index 000000000..7533e2724
--- /dev/null
+++ b/apps/web/src/core/utils/geofence.test.ts
@@ -0,0 +1,111 @@
+import { create } from "@bufbuild/protobuf";
+import { Protobuf } from "@meshtastic/sdk";
+import { describe, expect, it } from "vitest";
+import {
+ degToCoordI,
+ displayToMeters,
+ hasAnyNotify,
+ hasGeofence,
+ metersToDisplay,
+ pointInBoundingBox,
+ pointInGeofence,
+ unitSystemFromDisplayUnits,
+} from "./geofence.ts";
+
+const bbox = (west: number, south: number, east: number, north: number) =>
+ create(Protobuf.Mesh.BoundingBoxSchema, {
+ longitudeWestI: degToCoordI(west),
+ latitudeSouthI: degToCoordI(south),
+ longitudeEastI: degToCoordI(east),
+ latitudeNorthI: degToCoordI(north),
+ });
+
+const waypoint = (fields: Record) =>
+ create(Protobuf.Mesh.WaypointSchema, fields as never);
+
+describe("geofence – device unit system", () => {
+ it("maps DisplayUnits.IMPERIAL to imperial", () => {
+ expect(
+ unitSystemFromDisplayUnits(
+ Protobuf.Config.Config_DisplayConfig_DisplayUnits.IMPERIAL,
+ ),
+ ).toBe("imperial");
+ });
+ it("maps DisplayUnits.METRIC and undefined to metric", () => {
+ expect(
+ unitSystemFromDisplayUnits(
+ Protobuf.Config.Config_DisplayConfig_DisplayUnits.METRIC,
+ ),
+ ).toBe("metric");
+ expect(unitSystemFromDisplayUnits(undefined)).toBe("metric");
+ });
+
+ it("round-trips display <-> meters", () => {
+ expect(displayToMeters(1, "metric", false)).toBe(1);
+ expect(displayToMeters(1, "metric", true)).toBe(1000);
+ expect(Math.round(displayToMeters(1, "imperial", false))).toBe(0);
+ expect(Math.round(displayToMeters(1, "imperial", true))).toBe(1609);
+ expect(metersToDisplay(2000, "metric")).toBe(2);
+ expect(metersToDisplay(500, "metric")).toBe(500);
+ });
+});
+
+describe("geofence – point-in-region", () => {
+ it("returns false when neither shape set", () => {
+ expect(pointInGeofence([0, 0], waypoint({}))).toBe(false);
+ });
+
+ it("respects circular radius", () => {
+ const wp = waypoint({
+ latitudeI: degToCoordI(40),
+ longitudeI: degToCoordI(-74),
+ geofenceRadius: 1000,
+ });
+ expect(pointInGeofence([-74, 40], wp)).toBe(true);
+ expect(pointInGeofence([-74, 40.005], wp)).toBe(true);
+ expect(pointInGeofence([-74, 40.5], wp)).toBe(false);
+ });
+
+ it("respects bounding box (WSEN)", () => {
+ const wp = waypoint({
+ boundingBox: bbox(-74.1, 39.9, -73.9, 40.1),
+ });
+ expect(pointInGeofence([-74, 40], wp)).toBe(true);
+ expect(pointInGeofence([-74.05, 39.95], wp)).toBe(true);
+ expect(pointInGeofence([-73.5, 40], wp)).toBe(false);
+ expect(pointInGeofence([-74, 41], wp)).toBe(false);
+ });
+
+ it("OR-combines circle and box", () => {
+ const wp = waypoint({
+ latitudeI: degToCoordI(40),
+ longitudeI: degToCoordI(-74),
+ geofenceRadius: 100,
+ boundingBox: bbox(-70.1, 39.9, -69.9, 40.1),
+ });
+ expect(pointInGeofence([-74, 40], wp)).toBe(true);
+ expect(pointInGeofence([-70, 40], wp)).toBe(true);
+ expect(pointInGeofence([-72, 40], wp)).toBe(false);
+ });
+
+ it("handles anti-meridian crossing box", () => {
+ const wp = waypoint({ boundingBox: bbox(170, -10, -170, 10) });
+ expect(pointInBoundingBox([175, 0], wp.boundingBox!)).toBe(true);
+ expect(pointInBoundingBox([-175, 0], wp.boundingBox!)).toBe(true);
+ expect(pointInBoundingBox([0, 0], wp.boundingBox!)).toBe(false);
+ });
+});
+
+describe("geofence – helpers", () => {
+ it("hasGeofence detects either shape", () => {
+ expect(hasGeofence(waypoint({}))).toBe(false);
+ expect(hasGeofence(waypoint({ geofenceRadius: 10 }))).toBe(true);
+ expect(hasGeofence(waypoint({ boundingBox: bbox(0, 0, 1, 1) }))).toBe(true);
+ });
+
+ it("hasAnyNotify detects either flag", () => {
+ expect(hasAnyNotify(waypoint({}))).toBe(false);
+ expect(hasAnyNotify(waypoint({ notifyOnEnter: true }))).toBe(true);
+ expect(hasAnyNotify(waypoint({ notifyOnExit: true }))).toBe(true);
+ });
+});
diff --git a/apps/web/src/core/utils/geofence.ts b/apps/web/src/core/utils/geofence.ts
new file mode 100644
index 000000000..226650250
--- /dev/null
+++ b/apps/web/src/core/utils/geofence.ts
@@ -0,0 +1,99 @@
+import { Protobuf } from "@meshtastic/sdk";
+import { distanceMeters, type LngLat } from "./geo.ts";
+
+const INT_DEG = 1e7;
+const METERS_PER_FOOT = 0.3048;
+const METERS_PER_MILE = 1609.344;
+const IMPERIAL_MILES_THRESHOLD_METERS = METERS_PER_MILE / 2;
+
+export type UnitSystem = "metric" | "imperial";
+
+/**
+ * Waypoint UI reads the unit preference from the connected device's
+ * DisplayConfig (matches existing patterns like the position-precision
+ * selector in Channels/Channel.tsx). Falls back to metric when the config
+ * isn't loaded yet.
+ */
+export function unitSystemFromDisplayUnits(
+ units: Protobuf.Config.Config_DisplayConfig_DisplayUnits | undefined,
+): UnitSystem {
+ return units === Protobuf.Config.Config_DisplayConfig_DisplayUnits.IMPERIAL
+ ? "imperial"
+ : "metric";
+}
+
+export function metersToDisplay(meters: number, system: UnitSystem): number {
+ if (system === "imperial") {
+ return meters >= IMPERIAL_MILES_THRESHOLD_METERS
+ ? meters / METERS_PER_MILE
+ : meters / METERS_PER_FOOT;
+ }
+ return meters >= 1000 ? meters / 1000 : meters;
+}
+
+export function displayToMeters(
+ value: number,
+ system: UnitSystem,
+ useLarge: boolean,
+): number {
+ if (system === "imperial") {
+ return useLarge ? value * METERS_PER_MILE : value * METERS_PER_FOOT;
+ }
+ return useLarge ? value * 1000 : value;
+}
+
+export function pointInBoundingBox(
+ point: LngLat,
+ bbox: Protobuf.Mesh.BoundingBox,
+): boolean {
+ const [lng, lat] = point;
+ const west = bbox.longitudeWestI / INT_DEG;
+ const east = bbox.longitudeEastI / INT_DEG;
+ const south = bbox.latitudeSouthI / INT_DEG;
+ const north = bbox.latitudeNorthI / INT_DEG;
+
+ if (lat < south || lat > north) return false;
+
+ if (west <= east) {
+ return lng >= west && lng <= east;
+ }
+ // Anti-meridian crossing
+ return lng >= west || lng <= east;
+}
+
+export function pointInGeofence(
+ point: LngLat,
+ waypoint: Protobuf.Mesh.Waypoint,
+): boolean {
+ const center: LngLat = [
+ (waypoint.longitudeI ?? 0) / INT_DEG,
+ (waypoint.latitudeI ?? 0) / INT_DEG,
+ ];
+ if (waypoint.geofenceRadius > 0) {
+ if (distanceMeters(point, center) <= waypoint.geofenceRadius) {
+ return true;
+ }
+ }
+ if (waypoint.boundingBox) {
+ if (pointInBoundingBox(point, waypoint.boundingBox)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+export function hasGeofence(waypoint: Protobuf.Mesh.Waypoint): boolean {
+ return waypoint.geofenceRadius > 0 || waypoint.boundingBox !== undefined;
+}
+
+export function hasAnyNotify(waypoint: Protobuf.Mesh.Waypoint): boolean {
+ return waypoint.notifyOnEnter || waypoint.notifyOnExit;
+}
+
+export function coordToDeg(coordI: number | undefined): number {
+ return (coordI ?? 0) / INT_DEG;
+}
+
+export function degToCoordI(deg: number): number {
+ return Math.round(deg * INT_DEG);
+}
diff --git a/apps/web/src/core/utils/geofenceCrossings.test.ts b/apps/web/src/core/utils/geofenceCrossings.test.ts
new file mode 100644
index 000000000..bfdfcdf13
--- /dev/null
+++ b/apps/web/src/core/utils/geofenceCrossings.test.ts
@@ -0,0 +1,119 @@
+import { create } from "@bufbuild/protobuf";
+import type { WaypointWithMetadata } from "@core/stores";
+import { degToCoordI } from "@core/utils/geofence.ts";
+import { Protobuf } from "@meshtastic/sdk";
+import { describe, expect, it } from "vitest";
+import { GeofenceCrossings } from "./geofenceCrossings.ts";
+
+function wp(fields: Record): WaypointWithMetadata {
+ const proto = create(Protobuf.Mesh.WaypointSchema, fields as never);
+ return Object.assign(proto, {
+ metadata: { channel: 0, created: new Date(), from: 0 },
+ });
+}
+
+const center = { latitudeI: degToCoordI(40), longitudeI: degToCoordI(-74) };
+
+describe("GeofenceCrossings – baseline-first semantics", () => {
+ it("first sighting only records a baseline, no event", () => {
+ const c = new GeofenceCrossings();
+ const waypoints = [wp({ id: 1, ...center, geofenceRadius: 500, notifyOnEnter: true })];
+ expect(c.evaluate([-74, 40], 42, waypoints)).toEqual([]);
+ expect(c.evaluate([-70, 40], 42, waypoints)).toEqual([]);
+ });
+
+ it("emits enter on outside → inside transition", () => {
+ const c = new GeofenceCrossings();
+ const waypoints = [wp({ id: 1, ...center, geofenceRadius: 500, notifyOnEnter: true })];
+ // Baseline outside
+ c.evaluate([-70, 40], 42, waypoints);
+ const events = c.evaluate([-74, 40], 42, waypoints);
+ expect(events).toEqual([{ waypointId: 1, nodeNum: 42, kind: "enter" }]);
+ });
+
+ it("emits exit on inside → outside transition", () => {
+ const c = new GeofenceCrossings();
+ const waypoints = [wp({ id: 1, ...center, geofenceRadius: 500, notifyOnExit: true })];
+ c.evaluate([-74, 40], 42, waypoints);
+ const events = c.evaluate([-70, 40], 42, waypoints);
+ expect(events).toEqual([{ waypointId: 1, nodeNum: 42, kind: "exit" }]);
+ });
+
+ it("skips waypoints with no notify flag set", () => {
+ const c = new GeofenceCrossings();
+ const waypoints = [wp({ id: 1, ...center, geofenceRadius: 500 })];
+ c.evaluate([-70, 40], 42, waypoints);
+ expect(c.evaluate([-74, 40], 42, waypoints)).toEqual([]);
+ });
+
+ it("skips waypoints with no geofence shape", () => {
+ const c = new GeofenceCrossings();
+ const waypoints = [wp({ id: 1, notifyOnEnter: true })];
+ c.evaluate([-70, 40], 42, waypoints);
+ expect(c.evaluate([-74, 40], 42, waypoints)).toEqual([]);
+ });
+
+ it("respects notify_on_exit only", () => {
+ const c = new GeofenceCrossings();
+ const waypoints = [wp({ id: 1, ...center, geofenceRadius: 500, notifyOnExit: true })];
+ // Baseline outside then move inside: no notifyOnEnter → no event
+ c.evaluate([-70, 40], 42, waypoints);
+ expect(c.evaluate([-74, 40], 42, waypoints)).toEqual([]);
+ // Move back outside → exit event
+ expect(c.evaluate([-70, 40], 42, waypoints)).toEqual([
+ { waypointId: 1, nodeNum: 42, kind: "exit" },
+ ]);
+ });
+
+ it("tracks per-node state independently", () => {
+ const c = new GeofenceCrossings();
+ const waypoints = [
+ wp({ id: 1, ...center, geofenceRadius: 500, notifyOnEnter: true, notifyOnExit: true }),
+ ];
+ // Node 1 starts inside baseline; node 2 starts outside baseline
+ c.evaluate([-74, 40], 1, waypoints);
+ c.evaluate([-70, 40], 2, waypoints);
+ // Node 1 leaves → exit event, node 2 unchanged
+ expect(c.evaluate([-70, 40], 1, waypoints)).toEqual([
+ { waypointId: 1, nodeNum: 1, kind: "exit" },
+ ]);
+ expect(c.evaluate([-70, 40], 2, waypoints)).toEqual([]);
+ // Node 2 enters → enter event
+ expect(c.evaluate([-74, 40], 2, waypoints)).toEqual([
+ { waypointId: 1, nodeNum: 2, kind: "enter" },
+ ]);
+ });
+
+ it("tracks per-waypoint state independently", () => {
+ const c = new GeofenceCrossings();
+ const waypoints = [
+ wp({
+ id: 1,
+ latitudeI: degToCoordI(40),
+ longitudeI: degToCoordI(-74),
+ geofenceRadius: 500,
+ notifyOnEnter: true,
+ }),
+ wp({
+ id: 2,
+ latitudeI: degToCoordI(50),
+ longitudeI: degToCoordI(-100),
+ geofenceRadius: 500,
+ notifyOnEnter: true,
+ }),
+ ];
+ c.evaluate([-70, 40], 7, waypoints);
+ // Enter waypoint 1 only
+ const events = c.evaluate([-74, 40], 7, waypoints);
+ expect(events).toEqual([{ waypointId: 1, nodeNum: 7, kind: "enter" }]);
+ });
+
+ it("reset() clears state so next call re-baselines", () => {
+ const c = new GeofenceCrossings();
+ const waypoints = [wp({ id: 1, ...center, geofenceRadius: 500, notifyOnEnter: true })];
+ c.evaluate([-70, 40], 42, waypoints);
+ c.evaluate([-74, 40], 42, waypoints); // enter
+ c.reset();
+ expect(c.evaluate([-74, 40], 42, waypoints)).toEqual([]); // baseline again
+ });
+});
diff --git a/apps/web/src/core/utils/geofenceCrossings.ts b/apps/web/src/core/utils/geofenceCrossings.ts
new file mode 100644
index 000000000..a7796583e
--- /dev/null
+++ b/apps/web/src/core/utils/geofenceCrossings.ts
@@ -0,0 +1,57 @@
+import type { WaypointWithMetadata } from "@core/stores";
+import type { LngLat } from "@core/utils/geo.ts";
+import { hasAnyNotify, hasGeofence, pointInGeofence } from "@core/utils/geofence.ts";
+
+type CrossingKey = `${number}:${number}`;
+
+export type GeofenceEvent = {
+ waypointId: number;
+ nodeNum: number;
+ kind: "enter" | "exit";
+};
+
+/**
+ * Point-in-region tracker with baseline-first `(waypointId, nodeNum)` state.
+ * First sighting only sets a baseline (no event); subsequent transitions
+ * across the region boundary emit an `enter` or `exit` event when the
+ * matching `notify_on_*` flag is set.
+ *
+ * Callers must filter events for the favorites-only gate — this class is
+ * intentionally pure and knows nothing about node favorite state.
+ */
+export class GeofenceCrossings {
+ private state = new Map();
+
+ reset(): void {
+ this.state.clear();
+ }
+
+ evaluate(
+ point: LngLat,
+ nodeNum: number,
+ waypoints: readonly WaypointWithMetadata[],
+ ): GeofenceEvent[] {
+ const events: GeofenceEvent[] = [];
+ for (const wp of waypoints) {
+ if (!hasGeofence(wp) || !hasAnyNotify(wp)) continue;
+
+ const key = `${wp.id}:${nodeNum}` as CrossingKey;
+ const inside = pointInGeofence(point, wp);
+ const prior = this.state.get(key);
+
+ if (prior === undefined) {
+ this.state.set(key, inside);
+ continue;
+ }
+ if (prior === inside) continue;
+ this.state.set(key, inside);
+
+ if (inside && wp.notifyOnEnter) {
+ events.push({ waypointId: wp.id, nodeNum, kind: "enter" });
+ } else if (!inside && wp.notifyOnExit) {
+ events.push({ waypointId: wp.id, nodeNum, kind: "exit" });
+ }
+ }
+ return events;
+ }
+}
diff --git a/apps/web/src/pages/Map/index.tsx b/apps/web/src/pages/Map/index.tsx
index f9d4a4bfc..878357a46 100644
--- a/apps/web/src/pages/Map/index.tsx
+++ b/apps/web/src/pages/Map/index.tsx
@@ -14,6 +14,7 @@ import {
type HeatmapMode,
} from "@components/PageComponents/Map/Layers/HeatmapLayer.tsx";
import { NodesLayer } from "@components/PageComponents/Map/Layers/NodesLayer.tsx";
+import { GeofenceLayer } from "@components/PageComponents/Map/Layers/GeofenceLayer.tsx";
import { PrecisionLayer } from "@components/PageComponents/Map/Layers/PrecisionLayer.tsx";
import {
SNRLayer,
@@ -22,21 +23,26 @@ import {
} from "@components/PageComponents/Map/Layers/SNRLayer.tsx";
import { WaypointLayer } from "@components/PageComponents/Map/Layers/WaypointLayer.tsx";
import type { PopupState } from "@components/PageComponents/Map/Popups/PopupWrapper.tsx";
+import { WaypointEditDialog } from "@components/Dialog/WaypointEditDialog.tsx";
+import { BoundingBoxOverlay } from "@components/PageComponents/Map/BoundingBoxOverlay.tsx";
+import { useAppStore, useDevice, type WaypointWithMetadata } from "@core/stores";
import { PageLayout } from "@components/PageLayout.tsx";
import { Sidebar } from "@components/Sidebar.tsx";
+import { useBoundingBoxDraw } from "@core/hooks/useBoundingBoxDraw.ts";
import { useMapFitting } from "@core/hooks/useMapFitting.ts";
import {
useMyNodeAsProto,
useNodesAsProto,
} from "@core/hooks/useNodesAsProto.ts";
import { cn } from "@core/utils/cn.ts";
-import { hasPos, toLngLat } from "@core/utils/geo.ts";
+import { hasPos, type LngLat, toLngLat } from "@core/utils/geo.ts";
import type { Protobuf } from "@meshtastic/sdk";
import { numberToHexUnpadded } from "@noble/curves/utils.js";
-import { FunnelIcon, LocateFixedIcon } from "lucide-react";
+import { FunnelIcon, LocateFixedIcon, MapPinPlusIcon } from "lucide-react";
import {
useCallback,
useDeferredValue,
+ useEffect,
useId,
useMemo,
useRef,
@@ -69,6 +75,44 @@ const MapPage = () => {
const [expandedCluster, setExpandedCluster] = useState();
const [popupState, setPopupState] = useState();
+ // Waypoint editor state
+ const [editorOpen, setEditorOpen] = useState(false);
+ const [editorWaypoint, setEditorWaypoint] = useState();
+ const [editorInitialLngLat, setEditorInitialLngLat] = useState();
+ const [placementMode, setPlacementMode] = useState(false);
+ const boxDraw = useBoundingBoxDraw(mapRef);
+
+ const openEditor = useCallback((wp: WaypointWithMetadata) => {
+ setEditorWaypoint(wp);
+ setEditorInitialLngLat(undefined);
+ setEditorOpen(true);
+ }, []);
+
+ const openCreator = useCallback((lngLat: LngLat) => {
+ setEditorWaypoint(undefined);
+ setEditorInitialLngLat(lngLat);
+ setEditorOpen(true);
+ }, []);
+
+ useEffect(() => {
+ if (!placementMode) return;
+ const map = mapRef?.getMap();
+ if (!map) return;
+ const canvas = map.getCanvas();
+ const prev = canvas.style.cursor;
+ // Matches the `MapPinPlus` lucide icon used on the placement toggle button
+ // so the cursor advertises the same affordance while positioning a waypoint.
+ const pinSvg =
+ "data:image/svg+xml;utf8," +
+ encodeURIComponent(
+ '',
+ );
+ canvas.style.cursor = `url("${pinSvg}") 16 29, auto`;
+ return () => {
+ canvas.style.cursor = prev;
+ };
+ }, [mapRef, placementMode]);
+
const [visibilityState, setVisibilityState] = useState(
() => defaultVisibilityState,
);
@@ -178,10 +222,17 @@ const MapPage = () => {
[getNode, t, heatmapLayerElementId],
);
- // Node markers & clusters
- const onMapBackgroundClick = useCallback(() => {
- setExpandedCluster(undefined);
- }, []);
+ // Node markers & clusters + placement-mode capture
+ const onMapBackgroundClick = useCallback(
+ (event: MapLayerMouseEvent) => {
+ setExpandedCluster(undefined);
+ if (placementMode) {
+ openCreator([event.lngLat.lng, event.lngLat.lat]);
+ setPlacementMode(false);
+ }
+ },
+ [openCreator, placementMode],
+ );
const markerElements = useMemo(
() => (
@@ -232,9 +283,37 @@ const MapPage = () => {
isVisible={visibilityState.waypoints}
popupState={popupState}
setPopupState={setPopupState}
+ onEditWaypoint={openEditor}
/>
),
- [mapRef, myNode, visibilityState.waypoints, popupState],
+ [mapRef, myNode, visibilityState.waypoints, popupState, openEditor],
+ );
+
+ // Geofence overlays
+ const { waypoints } = useDevice();
+
+ // Deep-link focus from geofence alert toasts.
+ const focusWaypointId = useAppStore((s) => s.focusWaypointId);
+ const setFocusWaypointId = useAppStore((s) => s.setFocusWaypointId);
+ useEffect(() => {
+ if (focusWaypointId === undefined || !mapRef) return;
+ const wp = waypoints.find((w) => w.id === focusWaypointId);
+ if (!wp) return;
+ focusLngLat(toLngLat({ latitudeI: wp.latitudeI, longitudeI: wp.longitudeI }));
+ setPopupState({ type: "waypoint", waypoint: wp });
+ setFocusWaypointId(undefined);
+ }, [focusWaypointId, focusLngLat, mapRef, setFocusWaypointId, waypoints]);
+
+ const geofenceLayerElementId = useId();
+ const geofenceLayerElement = useMemo(
+ () => (
+
+ ),
+ [waypoints, visibilityState.geofences, geofenceLayerElementId],
);
return (
@@ -252,6 +331,7 @@ const MapPage = () => {
{markerElements}
{snrLayerElement}
{precisionCirclesElement}
+ {geofenceLayerElement}
{waypointLayerElement}
{snrHover && (
@@ -263,6 +343,65 @@ const MapPage = () => {
/>
)}
+
+ {placementMode && (
+
+ {t("waypointEdit.placementHint")}
+
+
+ )}
+
+ {
+ setEditorOpen(open);
+ if (!open) {
+ setEditorWaypoint(undefined);
+ setEditorInitialLngLat(undefined);
+ }
+ }}
+ waypoint={editorWaypoint}
+ initialLngLat={editorInitialLngLat}
+ channel={0}
+ mapRef={mapRef}
+ onRequestBoundingBoxDraw={boxDraw.beginDraw}
+ />
+
+ {boxDraw.active && (
+ <>
+
+ {t("waypointEdit.drawHint")}
+
+
+
+ {boxDraw.overlay?.start && boxDraw.overlay.current && mapRef && (
+
+ )}
+
+ >
+ )}
+
{myNode && hasPos(myNode?.position) && (
);
diff --git a/packages/protobufs/meshtastic/mesh.proto b/packages/protobufs/meshtastic/mesh.proto
index ecfdadd9a..907d34aa7 100644
--- a/packages/protobufs/meshtastic/mesh.proto
+++ b/packages/protobufs/meshtastic/mesh.proto
@@ -1475,6 +1475,59 @@ message Waypoint {
* Designator icon for the waypoint in the form of a unicode emoji
*/
fixed32 icon = 8;
+
+ /*
+ * Geofence circle radius in meters around (latitude_i, longitude_i).
+ * 0 disables the circular geofence.
+ */
+ uint32 geofence_radius = 9;
+
+ /*
+ * Optional axis-aligned rectangular geofence (WSEN order).
+ * A point is inside the geofence if it falls inside the circle OR the box.
+ */
+ optional BoundingBox bounding_box = 10;
+
+ /*
+ * When true, receivers alert on nodes crossing outside -> inside.
+ */
+ bool notify_on_enter = 11;
+
+ /*
+ * When true, receivers alert on nodes crossing inside -> outside.
+ */
+ bool notify_on_exit = 12;
+
+ /*
+ * When true, suppress alerts for nodes not marked as favorite locally.
+ */
+ bool notify_favorites_only = 13;
+}
+
+/*
+ * Axis-aligned rectangular region in the same 1e-7 degree encoding as
+ * Position. Field order matches GeoJSON bbox (west, south, east, north).
+ */
+message BoundingBox {
+ /*
+ * West edge longitude (1e-7 degrees).
+ */
+ sfixed32 longitude_west_i = 1;
+
+ /*
+ * South edge latitude (1e-7 degrees).
+ */
+ sfixed32 latitude_south_i = 2;
+
+ /*
+ * East edge longitude (1e-7 degrees).
+ */
+ sfixed32 longitude_east_i = 3;
+
+ /*
+ * North edge latitude (1e-7 degrees).
+ */
+ sfixed32 latitude_north_i = 4;
}
/*
diff --git a/packages/protobufs/package.json b/packages/protobufs/package.json
index f96874535..d16397a23 100644
--- a/packages/protobufs/package.json
+++ b/packages/protobufs/package.json
@@ -22,6 +22,7 @@
"@bufbuild/protobuf": "^2.12.1"
},
"devDependencies": {
+ "@bufbuild/buf": "^1.71.0",
"@bufbuild/protoc-gen-es": "^2.12.1",
"rimraf": "^6.0.0"
}
diff --git a/packages/protobufs/packages/ts/dist/meshtastic/admin_pb.ts b/packages/protobufs/packages/ts/dist/meshtastic/admin_pb.ts
index 9861594b9..8c8cbc7fe 100644
--- a/packages/protobufs/packages/ts/dist/meshtastic/admin_pb.ts
+++ b/packages/protobufs/packages/ts/dist/meshtastic/admin_pb.ts
@@ -1,8 +1,12 @@
-// @generated by protoc-gen-es v2.12.0 with parameter "target=ts"
+// @generated by protoc-gen-es v2.12.1 with parameter "target=ts"
// @generated from file meshtastic/admin.proto (package meshtastic, syntax proto3)
/* eslint-disable */
-import type { GenEnum, GenFile, GenMessage } from "@bufbuild/protobuf/codegenv2";
+import type {
+ GenEnum,
+ GenFile,
+ GenMessage,
+} from "@bufbuild/protobuf/codegenv2";
import { enumDesc, fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2";
import type { Channel } from "./channel_pb";
import { file_meshtastic_channel } from "./channel_pb";
@@ -12,7 +16,12 @@ import type { DeviceConnectionStatus } from "./connection_status_pb";
import { file_meshtastic_connection_status } from "./connection_status_pb";
import type { DeviceUIConfig } from "./device_ui_pb";
import { file_meshtastic_device_ui } from "./device_ui_pb";
-import type { DeviceMetadata, NodeRemoteHardwarePin, Position, User } from "./mesh_pb";
+import type {
+ DeviceMetadata,
+ NodeRemoteHardwarePin,
+ Position,
+ User,
+} from "./mesh_pb";
import { file_meshtastic_mesh } from "./mesh_pb";
import type { ModuleConfig } from "./module_config_pb";
import { file_meshtastic_module_config } from "./module_config_pb";
@@ -21,8 +30,17 @@ import type { Message } from "@bufbuild/protobuf";
/**
* Describes the file meshtastic/admin.proto.
*/
-export const file_meshtastic_admin: GenFile = /*@__PURE__*/
- fileDesc("ChZtZXNodGFzdGljL2FkbWluLnByb3RvEgptZXNodGFzdGljIqsbCgxBZG1pbk1lc3NhZ2USFwoPc2Vzc2lvbl9wYXNza2V5GGUgASgMEh0KE2dldF9jaGFubmVsX3JlcXVlc3QYASABKA1IABIzChRnZXRfY2hhbm5lbF9yZXNwb25zZRgCIAEoCzITLm1lc2h0YXN0aWMuQ2hhbm5lbEgAEhsKEWdldF9vd25lcl9yZXF1ZXN0GAMgASgISAASLgoSZ2V0X293bmVyX3Jlc3BvbnNlGAQgASgLMhAubWVzaHRhc3RpYy5Vc2VySAASQQoSZ2V0X2NvbmZpZ19yZXF1ZXN0GAUgASgOMiMubWVzaHRhc3RpYy5BZG1pbk1lc3NhZ2UuQ29uZmlnVHlwZUgAEjEKE2dldF9jb25maWdfcmVzcG9uc2UYBiABKAsyEi5tZXNodGFzdGljLkNvbmZpZ0gAEk4KGWdldF9tb2R1bGVfY29uZmlnX3JlcXVlc3QYByABKA4yKS5tZXNodGFzdGljLkFkbWluTWVzc2FnZS5Nb2R1bGVDb25maWdUeXBlSAASPgoaZ2V0X21vZHVsZV9jb25maWdfcmVzcG9uc2UYCCABKAsyGC5tZXNodGFzdGljLk1vZHVsZUNvbmZpZ0gAEjQKKmdldF9jYW5uZWRfbWVzc2FnZV9tb2R1bGVfbWVzc2FnZXNfcmVxdWVzdBgKIAEoCEgAEjUKK2dldF9jYW5uZWRfbWVzc2FnZV9tb2R1bGVfbWVzc2FnZXNfcmVzcG9uc2UYCyABKAlIABIlChtnZXRfZGV2aWNlX21ldGFkYXRhX3JlcXVlc3QYDCABKAhIABJCChxnZXRfZGV2aWNlX21ldGFkYXRhX3Jlc3BvbnNlGA0gASgLMhoubWVzaHRhc3RpYy5EZXZpY2VNZXRhZGF0YUgAEh4KFGdldF9yaW5ndG9uZV9yZXF1ZXN0GA4gASgISAASHwoVZ2V0X3Jpbmd0b25lX3Jlc3BvbnNlGA8gASgJSAASLgokZ2V0X2RldmljZV9jb25uZWN0aW9uX3N0YXR1c19yZXF1ZXN0GBAgASgISAASUwolZ2V0X2RldmljZV9jb25uZWN0aW9uX3N0YXR1c19yZXNwb25zZRgRIAEoCzIiLm1lc2h0YXN0aWMuRGV2aWNlQ29ubmVjdGlvblN0YXR1c0gAEjEKDHNldF9oYW1fbW9kZRgSIAEoCzIZLm1lc2h0YXN0aWMuSGFtUGFyYW1ldGVyc0gAEi8KJWdldF9ub2RlX3JlbW90ZV9oYXJkd2FyZV9waW5zX3JlcXVlc3QYEyABKAhIABJcCiZnZXRfbm9kZV9yZW1vdGVfaGFyZHdhcmVfcGluc19yZXNwb25zZRgUIAEoCzIqLm1lc2h0YXN0aWMuTm9kZVJlbW90ZUhhcmR3YXJlUGluc1Jlc3BvbnNlSAASIAoWZW50ZXJfZGZ1X21vZGVfcmVxdWVzdBgVIAEoCEgAEh0KE2RlbGV0ZV9maWxlX3JlcXVlc3QYFiABKAlIABITCglzZXRfc2NhbGUYFyABKA1IABJFChJiYWNrdXBfcHJlZmVyZW5jZXMYGCABKA4yJy5tZXNodGFzdGljLkFkbWluTWVzc2FnZS5CYWNrdXBMb2NhdGlvbkgAEkYKE3Jlc3RvcmVfcHJlZmVyZW5jZXMYGSABKA4yJy5tZXNodGFzdGljLkFkbWluTWVzc2FnZS5CYWNrdXBMb2NhdGlvbkgAEkwKGXJlbW92ZV9iYWNrdXBfcHJlZmVyZW5jZXMYGiABKA4yJy5tZXNodGFzdGljLkFkbWluTWVzc2FnZS5CYWNrdXBMb2NhdGlvbkgAEj8KEHNlbmRfaW5wdXRfZXZlbnQYGyABKAsyIy5tZXNodGFzdGljLkFkbWluTWVzc2FnZS5JbnB1dEV2ZW50SAASJQoJc2V0X293bmVyGCAgASgLMhAubWVzaHRhc3RpYy5Vc2VySAASKgoLc2V0X2NoYW5uZWwYISABKAsyEy5tZXNodGFzdGljLkNoYW5uZWxIABIoCgpzZXRfY29uZmlnGCIgASgLMhIubWVzaHRhc3RpYy5Db25maWdIABI1ChFzZXRfbW9kdWxlX2NvbmZpZxgjIAEoCzIYLm1lc2h0YXN0aWMuTW9kdWxlQ29uZmlnSAASLAoic2V0X2Nhbm5lZF9tZXNzYWdlX21vZHVsZV9tZXNzYWdlcxgkIAEoCUgAEh4KFHNldF9yaW5ndG9uZV9tZXNzYWdlGCUgASgJSAASGwoRcmVtb3ZlX2J5X25vZGVudW0YJiABKA1IABIbChFzZXRfZmF2b3JpdGVfbm9kZRgnIAEoDUgAEh4KFHJlbW92ZV9mYXZvcml0ZV9ub2RlGCggASgNSAASMgoSc2V0X2ZpeGVkX3Bvc2l0aW9uGCkgASgLMhQubWVzaHRhc3RpYy5Qb3NpdGlvbkgAEh8KFXJlbW92ZV9maXhlZF9wb3NpdGlvbhgqIAEoCEgAEhcKDXNldF90aW1lX29ubHkYKyABKAdIABIfChVnZXRfdWlfY29uZmlnX3JlcXVlc3QYLCABKAhIABI8ChZnZXRfdWlfY29uZmlnX3Jlc3BvbnNlGC0gASgLMhoubWVzaHRhc3RpYy5EZXZpY2VVSUNvbmZpZ0gAEjUKD3N0b3JlX3VpX2NvbmZpZxguIAEoCzIaLm1lc2h0YXN0aWMuRGV2aWNlVUlDb25maWdIABIaChBzZXRfaWdub3JlZF9ub2RlGC8gASgNSAASHQoTcmVtb3ZlX2lnbm9yZWRfbm9kZRgwIAEoDUgAEhsKEXRvZ2dsZV9tdXRlZF9ub2RlGDEgASgNSAASHQoTYmVnaW5fZWRpdF9zZXR0aW5ncxhAIAEoCEgAEh4KFGNvbW1pdF9lZGl0X3NldHRpbmdzGEEgASgISAASMAoLYWRkX2NvbnRhY3QYQiABKAsyGS5tZXNodGFzdGljLlNoYXJlZENvbnRhY3RIABI8ChBrZXlfdmVyaWZpY2F0aW9uGEMgASgLMiAubWVzaHRhc3RpYy5LZXlWZXJpZmljYXRpb25BZG1pbkgAEh4KFGZhY3RvcnlfcmVzZXRfZGV2aWNlGF4gASgFSAASIAoScmVib290X290YV9zZWNvbmRzGF8gASgFQgIYAUgAEhgKDmV4aXRfc2ltdWxhdG9yGGAgASgISAASGAoOcmVib290X3NlY29uZHMYYSABKAVIABIaChBzaHV0ZG93bl9zZWNvbmRzGGIgASgFSAASHgoUZmFjdG9yeV9yZXNldF9jb25maWcYYyABKAVIABIWCgxub2RlZGJfcmVzZXQYZCABKAhIABI4CgtvdGFfcmVxdWVzdBhmIAEoCzIhLm1lc2h0YXN0aWMuQWRtaW5NZXNzYWdlLk9UQUV2ZW50SAASMQoNc2Vuc29yX2NvbmZpZxhnIAEoCzIYLm1lc2h0YXN0aWMuU2Vuc29yQ29uZmlnSAASMQoNbG9ja2Rvd25fYXV0aBhoIAEoCzIYLm1lc2h0YXN0aWMuTG9ja2Rvd25BdXRoSAAaUwoKSW5wdXRFdmVudBISCgpldmVudF9jb2RlGAEgASgNEg8KB2tiX2NoYXIYAiABKA0SDwoHdG91Y2hfeBgDIAEoDRIPCgd0b3VjaF95GAQgASgNGkoKCE9UQUV2ZW50EiwKD3JlYm9vdF9vdGFfbW9kZRgBIAEoDjITLm1lc2h0YXN0aWMuT1RBTW9kZRIQCghvdGFfaGFzaBgCIAEoDCLWAQoKQ29uZmlnVHlwZRIRCg1ERVZJQ0VfQ09ORklHEAASEwoPUE9TSVRJT05fQ09ORklHEAESEAoMUE9XRVJfQ09ORklHEAISEgoOTkVUV09SS19DT05GSUcQAxISCg5ESVNQTEFZX0NPTkZJRxAEEg8KC0xPUkFfQ09ORklHEAUSFAoQQkxVRVRPT1RIX0NPTkZJRxAGEhMKD1NFQ1VSSVRZX0NPTkZJRxAHEhUKEVNFU1NJT05LRVlfQ09ORklHEAgSEwoPREVWSUNFVUlfQ09ORklHEAkigwMKEE1vZHVsZUNvbmZpZ1R5cGUSDwoLTVFUVF9DT05GSUcQABIRCg1TRVJJQUxfQ09ORklHEAESEwoPRVhUTk9USUZfQ09ORklHEAISFwoTU1RPUkVGT1JXQVJEX0NPTkZJRxADEhQKEFJBTkdFVEVTVF9DT05GSUcQBBIUChBURUxFTUVUUllfQ09ORklHEAUSFAoQQ0FOTkVETVNHX0NPTkZJRxAGEhAKDEFVRElPX0NPTkZJRxAHEhkKFVJFTU9URUhBUkRXQVJFX0NPTkZJRxAIEhcKE05FSUdIQk9SSU5GT19DT05GSUcQCRIaChZBTUJJRU5UTElHSFRJTkdfQ09ORklHEAoSGgoWREVURUNUSU9OU0VOU09SX0NPTkZJRxALEhUKEVBBWENPVU5URVJfQ09ORklHEAwSGAoUU1RBVFVTTUVTU0FHRV9DT05GSUcQDRIcChhUUkFGRklDTUFOQUdFTUVOVF9DT05GSUcQDhIOCgpUQUtfQ09ORklHEA8iIwoOQmFja3VwTG9jYXRpb24SCQoFRkxBU0gQABIGCgJTRBABQhEKD3BheWxvYWRfdmFyaWFudCKWAQoMTG9ja2Rvd25BdXRoEhIKCnBhc3NwaHJhc2UYASABKAwSFwoPYm9vdHNfcmVtYWluaW5nGAIgASgNEhkKEXZhbGlkX3VudGlsX2Vwb2NoGAMgASgNEhAKCGxvY2tfbm93GAQgASgIEhsKE21heF9zZXNzaW9uX3NlY29uZHMYBSABKA0SDwoHZGlzYWJsZRgGIAEoCCJuCg1IYW1QYXJhbWV0ZXJzEhEKCWNhbGxfc2lnbhgBIAEoCRIQCgh0eF9wb3dlchgCIAEoBRIRCglmcmVxdWVuY3kYAyABKAISEgoKc2hvcnRfbmFtZRgEIAEoCRIRCglsb25nX25hbWUYBSABKAkiZgoeTm9kZVJlbW90ZUhhcmR3YXJlUGluc1Jlc3BvbnNlEkQKGW5vZGVfcmVtb3RlX2hhcmR3YXJlX3BpbnMYASADKAsyIS5tZXNodGFzdGljLk5vZGVSZW1vdGVIYXJkd2FyZVBpbiJzCg1TaGFyZWRDb250YWN0EhAKCG5vZGVfbnVtGAEgASgNEh4KBHVzZXIYAiABKAsyEC5tZXNodGFzdGljLlVzZXISFQoNc2hvdWxkX2lnbm9yZRgDIAEoCBIZChFtYW51YWxseV92ZXJpZmllZBgEIAEoCCKcAgoUS2V5VmVyaWZpY2F0aW9uQWRtaW4SQgoMbWVzc2FnZV90eXBlGAEgASgOMiwubWVzaHRhc3RpYy5LZXlWZXJpZmljYXRpb25BZG1pbi5NZXNzYWdlVHlwZRIWCg5yZW1vdGVfbm9kZW51bRgCIAEoDRINCgVub25jZRgDIAEoBBIcCg9zZWN1cml0eV9udW1iZXIYBCABKA1IAIgBASJnCgtNZXNzYWdlVHlwZRIZChVJTklUSUFURV9WRVJJRklDQVRJT04QABIbChdQUk9WSURFX1NFQ1VSSVRZX05VTUJFUhABEg0KCURPX1ZFUklGWRACEhEKDURPX05PVF9WRVJJRlkQA0ISChBfc2VjdXJpdHlfbnVtYmVyIs4BCgxTZW5zb3JDb25maWcSLgoMc2NkNHhfY29uZmlnGAEgASgLMhgubWVzaHRhc3RpYy5TQ0Q0WF9jb25maWcSLgoMc2VuNXhfY29uZmlnGAIgASgLMhgubWVzaHRhc3RpYy5TRU41WF9jb25maWcSLgoMc2NkMzBfY29uZmlnGAMgASgLMhgubWVzaHRhc3RpYy5TQ0QzMF9jb25maWcSLgoMc2h0eHhfY29uZmlnGAQgASgLMhgubWVzaHRhc3RpYy5TSFRYWF9jb25maWci4gIKDFNDRDRYX2NvbmZpZxIUCgdzZXRfYXNjGAEgASgISACIAQESIAoTc2V0X3RhcmdldF9jbzJfY29uYxgCIAEoDUgBiAEBEhwKD3NldF90ZW1wZXJhdHVyZRgDIAEoAkgCiAEBEhkKDHNldF9hbHRpdHVkZRgEIAEoDUgDiAEBEiEKFHNldF9hbWJpZW50X3ByZXNzdXJlGAUgASgNSASIAQESGgoNZmFjdG9yeV9yZXNldBgGIAEoCEgFiAEBEhsKDnNldF9wb3dlcl9tb2RlGAcgASgISAaIAQFCCgoIX3NldF9hc2NCFgoUX3NldF90YXJnZXRfY28yX2NvbmNCEgoQX3NldF90ZW1wZXJhdHVyZUIPCg1fc2V0X2FsdGl0dWRlQhcKFV9zZXRfYW1iaWVudF9wcmVzc3VyZUIQCg5fZmFjdG9yeV9yZXNldEIRCg9fc2V0X3Bvd2VyX21vZGUidgoMU0VONVhfY29uZmlnEhwKD3NldF90ZW1wZXJhdHVyZRgBIAEoAkgAiAEBEh4KEXNldF9vbmVfc2hvdF9tb2RlGAIgASgISAGIAQFCEgoQX3NldF90ZW1wZXJhdHVyZUIUChJfc2V0X29uZV9zaG90X21vZGUitAIKDFNDRDMwX2NvbmZpZxIUCgdzZXRfYXNjGAEgASgISACIAQESIAoTc2V0X3RhcmdldF9jbzJfY29uYxgCIAEoDUgBiAEBEhwKD3NldF90ZW1wZXJhdHVyZRgDIAEoAkgCiAEBEhkKDHNldF9hbHRpdHVkZRgEIAEoDUgDiAEBEiUKGHNldF9tZWFzdXJlbWVudF9pbnRlcnZhbBgFIAEoDUgEiAEBEhcKCnNvZnRfcmVzZXQYBiABKAhIBYgBAUIKCghfc2V0X2FzY0IWChRfc2V0X3RhcmdldF9jbzJfY29uY0ISChBfc2V0X3RlbXBlcmF0dXJlQg8KDV9zZXRfYWx0aXR1ZGVCGwoZX3NldF9tZWFzdXJlbWVudF9pbnRlcnZhbEINCgtfc29mdF9yZXNldCI6CgxTSFRYWF9jb25maWcSGQoMc2V0X2FjY3VyYWN5GAEgASgNSACIAQFCDwoNX3NldF9hY2N1cmFjeSo3CgdPVEFNb2RlEhEKDU5PX1JFQk9PVF9PVEEQABILCgdPVEFfQkxFEAESDAoIT1RBX1dJRkkQAkJhChRvcmcubWVzaHRhc3RpYy5wcm90b0ILQWRtaW5Qcm90b3NaImdpdGh1Yi5jb20vbWVzaHRhc3RpYy9nby9nZW5lcmF0ZWSqAhRNZXNodGFzdGljLlByb3RvYnVmc7oCAGIGcHJvdG8z", [file_meshtastic_channel, file_meshtastic_config, file_meshtastic_connection_status, file_meshtastic_device_ui, file_meshtastic_mesh, file_meshtastic_module_config]);
+export const file_meshtastic_admin: GenFile /*@__PURE__*/ = fileDesc(
+ "ChZtZXNodGFzdGljL2FkbWluLnByb3RvEgptZXNodGFzdGljIqsbCgxBZG1pbk1lc3NhZ2USFwoPc2Vzc2lvbl9wYXNza2V5GGUgASgMEh0KE2dldF9jaGFubmVsX3JlcXVlc3QYASABKA1IABIzChRnZXRfY2hhbm5lbF9yZXNwb25zZRgCIAEoCzITLm1lc2h0YXN0aWMuQ2hhbm5lbEgAEhsKEWdldF9vd25lcl9yZXF1ZXN0GAMgASgISAASLgoSZ2V0X293bmVyX3Jlc3BvbnNlGAQgASgLMhAubWVzaHRhc3RpYy5Vc2VySAASQQoSZ2V0X2NvbmZpZ19yZXF1ZXN0GAUgASgOMiMubWVzaHRhc3RpYy5BZG1pbk1lc3NhZ2UuQ29uZmlnVHlwZUgAEjEKE2dldF9jb25maWdfcmVzcG9uc2UYBiABKAsyEi5tZXNodGFzdGljLkNvbmZpZ0gAEk4KGWdldF9tb2R1bGVfY29uZmlnX3JlcXVlc3QYByABKA4yKS5tZXNodGFzdGljLkFkbWluTWVzc2FnZS5Nb2R1bGVDb25maWdUeXBlSAASPgoaZ2V0X21vZHVsZV9jb25maWdfcmVzcG9uc2UYCCABKAsyGC5tZXNodGFzdGljLk1vZHVsZUNvbmZpZ0gAEjQKKmdldF9jYW5uZWRfbWVzc2FnZV9tb2R1bGVfbWVzc2FnZXNfcmVxdWVzdBgKIAEoCEgAEjUKK2dldF9jYW5uZWRfbWVzc2FnZV9tb2R1bGVfbWVzc2FnZXNfcmVzcG9uc2UYCyABKAlIABIlChtnZXRfZGV2aWNlX21ldGFkYXRhX3JlcXVlc3QYDCABKAhIABJCChxnZXRfZGV2aWNlX21ldGFkYXRhX3Jlc3BvbnNlGA0gASgLMhoubWVzaHRhc3RpYy5EZXZpY2VNZXRhZGF0YUgAEh4KFGdldF9yaW5ndG9uZV9yZXF1ZXN0GA4gASgISAASHwoVZ2V0X3Jpbmd0b25lX3Jlc3BvbnNlGA8gASgJSAASLgokZ2V0X2RldmljZV9jb25uZWN0aW9uX3N0YXR1c19yZXF1ZXN0GBAgASgISAASUwolZ2V0X2RldmljZV9jb25uZWN0aW9uX3N0YXR1c19yZXNwb25zZRgRIAEoCzIiLm1lc2h0YXN0aWMuRGV2aWNlQ29ubmVjdGlvblN0YXR1c0gAEjEKDHNldF9oYW1fbW9kZRgSIAEoCzIZLm1lc2h0YXN0aWMuSGFtUGFyYW1ldGVyc0gAEi8KJWdldF9ub2RlX3JlbW90ZV9oYXJkd2FyZV9waW5zX3JlcXVlc3QYEyABKAhIABJcCiZnZXRfbm9kZV9yZW1vdGVfaGFyZHdhcmVfcGluc19yZXNwb25zZRgUIAEoCzIqLm1lc2h0YXN0aWMuTm9kZVJlbW90ZUhhcmR3YXJlUGluc1Jlc3BvbnNlSAASIAoWZW50ZXJfZGZ1X21vZGVfcmVxdWVzdBgVIAEoCEgAEh0KE2RlbGV0ZV9maWxlX3JlcXVlc3QYFiABKAlIABITCglzZXRfc2NhbGUYFyABKA1IABJFChJiYWNrdXBfcHJlZmVyZW5jZXMYGCABKA4yJy5tZXNodGFzdGljLkFkbWluTWVzc2FnZS5CYWNrdXBMb2NhdGlvbkgAEkYKE3Jlc3RvcmVfcHJlZmVyZW5jZXMYGSABKA4yJy5tZXNodGFzdGljLkFkbWluTWVzc2FnZS5CYWNrdXBMb2NhdGlvbkgAEkwKGXJlbW92ZV9iYWNrdXBfcHJlZmVyZW5jZXMYGiABKA4yJy5tZXNodGFzdGljLkFkbWluTWVzc2FnZS5CYWNrdXBMb2NhdGlvbkgAEj8KEHNlbmRfaW5wdXRfZXZlbnQYGyABKAsyIy5tZXNodGFzdGljLkFkbWluTWVzc2FnZS5JbnB1dEV2ZW50SAASJQoJc2V0X293bmVyGCAgASgLMhAubWVzaHRhc3RpYy5Vc2VySAASKgoLc2V0X2NoYW5uZWwYISABKAsyEy5tZXNodGFzdGljLkNoYW5uZWxIABIoCgpzZXRfY29uZmlnGCIgASgLMhIubWVzaHRhc3RpYy5Db25maWdIABI1ChFzZXRfbW9kdWxlX2NvbmZpZxgjIAEoCzIYLm1lc2h0YXN0aWMuTW9kdWxlQ29uZmlnSAASLAoic2V0X2Nhbm5lZF9tZXNzYWdlX21vZHVsZV9tZXNzYWdlcxgkIAEoCUgAEh4KFHNldF9yaW5ndG9uZV9tZXNzYWdlGCUgASgJSAASGwoRcmVtb3ZlX2J5X25vZGVudW0YJiABKA1IABIbChFzZXRfZmF2b3JpdGVfbm9kZRgnIAEoDUgAEh4KFHJlbW92ZV9mYXZvcml0ZV9ub2RlGCggASgNSAASMgoSc2V0X2ZpeGVkX3Bvc2l0aW9uGCkgASgLMhQubWVzaHRhc3RpYy5Qb3NpdGlvbkgAEh8KFXJlbW92ZV9maXhlZF9wb3NpdGlvbhgqIAEoCEgAEhcKDXNldF90aW1lX29ubHkYKyABKAdIABIfChVnZXRfdWlfY29uZmlnX3JlcXVlc3QYLCABKAhIABI8ChZnZXRfdWlfY29uZmlnX3Jlc3BvbnNlGC0gASgLMhoubWVzaHRhc3RpYy5EZXZpY2VVSUNvbmZpZ0gAEjUKD3N0b3JlX3VpX2NvbmZpZxguIAEoCzIaLm1lc2h0YXN0aWMuRGV2aWNlVUlDb25maWdIABIaChBzZXRfaWdub3JlZF9ub2RlGC8gASgNSAASHQoTcmVtb3ZlX2lnbm9yZWRfbm9kZRgwIAEoDUgAEhsKEXRvZ2dsZV9tdXRlZF9ub2RlGDEgASgNSAASHQoTYmVnaW5fZWRpdF9zZXR0aW5ncxhAIAEoCEgAEh4KFGNvbW1pdF9lZGl0X3NldHRpbmdzGEEgASgISAASMAoLYWRkX2NvbnRhY3QYQiABKAsyGS5tZXNodGFzdGljLlNoYXJlZENvbnRhY3RIABI8ChBrZXlfdmVyaWZpY2F0aW9uGEMgASgLMiAubWVzaHRhc3RpYy5LZXlWZXJpZmljYXRpb25BZG1pbkgAEh4KFGZhY3RvcnlfcmVzZXRfZGV2aWNlGF4gASgFSAASIAoScmVib290X290YV9zZWNvbmRzGF8gASgFQgIYAUgAEhgKDmV4aXRfc2ltdWxhdG9yGGAgASgISAASGAoOcmVib290X3NlY29uZHMYYSABKAVIABIaChBzaHV0ZG93bl9zZWNvbmRzGGIgASgFSAASHgoUZmFjdG9yeV9yZXNldF9jb25maWcYYyABKAVIABIWCgxub2RlZGJfcmVzZXQYZCABKAhIABI4CgtvdGFfcmVxdWVzdBhmIAEoCzIhLm1lc2h0YXN0aWMuQWRtaW5NZXNzYWdlLk9UQUV2ZW50SAASMQoNc2Vuc29yX2NvbmZpZxhnIAEoCzIYLm1lc2h0YXN0aWMuU2Vuc29yQ29uZmlnSAASMQoNbG9ja2Rvd25fYXV0aBhoIAEoCzIYLm1lc2h0YXN0aWMuTG9ja2Rvd25BdXRoSAAaUwoKSW5wdXRFdmVudBISCgpldmVudF9jb2RlGAEgASgNEg8KB2tiX2NoYXIYAiABKA0SDwoHdG91Y2hfeBgDIAEoDRIPCgd0b3VjaF95GAQgASgNGkoKCE9UQUV2ZW50EiwKD3JlYm9vdF9vdGFfbW9kZRgBIAEoDjITLm1lc2h0YXN0aWMuT1RBTW9kZRIQCghvdGFfaGFzaBgCIAEoDCLWAQoKQ29uZmlnVHlwZRIRCg1ERVZJQ0VfQ09ORklHEAASEwoPUE9TSVRJT05fQ09ORklHEAESEAoMUE9XRVJfQ09ORklHEAISEgoOTkVUV09SS19DT05GSUcQAxISCg5ESVNQTEFZX0NPTkZJRxAEEg8KC0xPUkFfQ09ORklHEAUSFAoQQkxVRVRPT1RIX0NPTkZJRxAGEhMKD1NFQ1VSSVRZX0NPTkZJRxAHEhUKEVNFU1NJT05LRVlfQ09ORklHEAgSEwoPREVWSUNFVUlfQ09ORklHEAkigwMKEE1vZHVsZUNvbmZpZ1R5cGUSDwoLTVFUVF9DT05GSUcQABIRCg1TRVJJQUxfQ09ORklHEAESEwoPRVhUTk9USUZfQ09ORklHEAISFwoTU1RPUkVGT1JXQVJEX0NPTkZJRxADEhQKEFJBTkdFVEVTVF9DT05GSUcQBBIUChBURUxFTUVUUllfQ09ORklHEAUSFAoQQ0FOTkVETVNHX0NPTkZJRxAGEhAKDEFVRElPX0NPTkZJRxAHEhkKFVJFTU9URUhBUkRXQVJFX0NPTkZJRxAIEhcKE05FSUdIQk9SSU5GT19DT05GSUcQCRIaChZBTUJJRU5UTElHSFRJTkdfQ09ORklHEAoSGgoWREVURUNUSU9OU0VOU09SX0NPTkZJRxALEhUKEVBBWENPVU5URVJfQ09ORklHEAwSGAoUU1RBVFVTTUVTU0FHRV9DT05GSUcQDRIcChhUUkFGRklDTUFOQUdFTUVOVF9DT05GSUcQDhIOCgpUQUtfQ09ORklHEA8iIwoOQmFja3VwTG9jYXRpb24SCQoFRkxBU0gQABIGCgJTRBABQhEKD3BheWxvYWRfdmFyaWFudCKWAQoMTG9ja2Rvd25BdXRoEhIKCnBhc3NwaHJhc2UYASABKAwSFwoPYm9vdHNfcmVtYWluaW5nGAIgASgNEhkKEXZhbGlkX3VudGlsX2Vwb2NoGAMgASgNEhAKCGxvY2tfbm93GAQgASgIEhsKE21heF9zZXNzaW9uX3NlY29uZHMYBSABKA0SDwoHZGlzYWJsZRgGIAEoCCJuCg1IYW1QYXJhbWV0ZXJzEhEKCWNhbGxfc2lnbhgBIAEoCRIQCgh0eF9wb3dlchgCIAEoBRIRCglmcmVxdWVuY3kYAyABKAISEgoKc2hvcnRfbmFtZRgEIAEoCRIRCglsb25nX25hbWUYBSABKAkiZgoeTm9kZVJlbW90ZUhhcmR3YXJlUGluc1Jlc3BvbnNlEkQKGW5vZGVfcmVtb3RlX2hhcmR3YXJlX3BpbnMYASADKAsyIS5tZXNodGFzdGljLk5vZGVSZW1vdGVIYXJkd2FyZVBpbiJzCg1TaGFyZWRDb250YWN0EhAKCG5vZGVfbnVtGAEgASgNEh4KBHVzZXIYAiABKAsyEC5tZXNodGFzdGljLlVzZXISFQoNc2hvdWxkX2lnbm9yZRgDIAEoCBIZChFtYW51YWxseV92ZXJpZmllZBgEIAEoCCKcAgoUS2V5VmVyaWZpY2F0aW9uQWRtaW4SQgoMbWVzc2FnZV90eXBlGAEgASgOMiwubWVzaHRhc3RpYy5LZXlWZXJpZmljYXRpb25BZG1pbi5NZXNzYWdlVHlwZRIWCg5yZW1vdGVfbm9kZW51bRgCIAEoDRINCgVub25jZRgDIAEoBBIcCg9zZWN1cml0eV9udW1iZXIYBCABKA1IAIgBASJnCgtNZXNzYWdlVHlwZRIZChVJTklUSUFURV9WRVJJRklDQVRJT04QABIbChdQUk9WSURFX1NFQ1VSSVRZX05VTUJFUhABEg0KCURPX1ZFUklGWRACEhEKDURPX05PVF9WRVJJRlkQA0ISChBfc2VjdXJpdHlfbnVtYmVyIs4BCgxTZW5zb3JDb25maWcSLgoMc2NkNHhfY29uZmlnGAEgASgLMhgubWVzaHRhc3RpYy5TQ0Q0WF9jb25maWcSLgoMc2VuNXhfY29uZmlnGAIgASgLMhgubWVzaHRhc3RpYy5TRU41WF9jb25maWcSLgoMc2NkMzBfY29uZmlnGAMgASgLMhgubWVzaHRhc3RpYy5TQ0QzMF9jb25maWcSLgoMc2h0eHhfY29uZmlnGAQgASgLMhgubWVzaHRhc3RpYy5TSFRYWF9jb25maWci4gIKDFNDRDRYX2NvbmZpZxIUCgdzZXRfYXNjGAEgASgISACIAQESIAoTc2V0X3RhcmdldF9jbzJfY29uYxgCIAEoDUgBiAEBEhwKD3NldF90ZW1wZXJhdHVyZRgDIAEoAkgCiAEBEhkKDHNldF9hbHRpdHVkZRgEIAEoDUgDiAEBEiEKFHNldF9hbWJpZW50X3ByZXNzdXJlGAUgASgNSASIAQESGgoNZmFjdG9yeV9yZXNldBgGIAEoCEgFiAEBEhsKDnNldF9wb3dlcl9tb2RlGAcgASgISAaIAQFCCgoIX3NldF9hc2NCFgoUX3NldF90YXJnZXRfY28yX2NvbmNCEgoQX3NldF90ZW1wZXJhdHVyZUIPCg1fc2V0X2FsdGl0dWRlQhcKFV9zZXRfYW1iaWVudF9wcmVzc3VyZUIQCg5fZmFjdG9yeV9yZXNldEIRCg9fc2V0X3Bvd2VyX21vZGUidgoMU0VONVhfY29uZmlnEhwKD3NldF90ZW1wZXJhdHVyZRgBIAEoAkgAiAEBEh4KEXNldF9vbmVfc2hvdF9tb2RlGAIgASgISAGIAQFCEgoQX3NldF90ZW1wZXJhdHVyZUIUChJfc2V0X29uZV9zaG90X21vZGUitAIKDFNDRDMwX2NvbmZpZxIUCgdzZXRfYXNjGAEgASgISACIAQESIAoTc2V0X3RhcmdldF9jbzJfY29uYxgCIAEoDUgBiAEBEhwKD3NldF90ZW1wZXJhdHVyZRgDIAEoAkgCiAEBEhkKDHNldF9hbHRpdHVkZRgEIAEoDUgDiAEBEiUKGHNldF9tZWFzdXJlbWVudF9pbnRlcnZhbBgFIAEoDUgEiAEBEhcKCnNvZnRfcmVzZXQYBiABKAhIBYgBAUIKCghfc2V0X2FzY0IWChRfc2V0X3RhcmdldF9jbzJfY29uY0ISChBfc2V0X3RlbXBlcmF0dXJlQg8KDV9zZXRfYWx0aXR1ZGVCGwoZX3NldF9tZWFzdXJlbWVudF9pbnRlcnZhbEINCgtfc29mdF9yZXNldCI6CgxTSFRYWF9jb25maWcSGQoMc2V0X2FjY3VyYWN5GAEgASgNSACIAQFCDwoNX3NldF9hY2N1cmFjeSo3CgdPVEFNb2RlEhEKDU5PX1JFQk9PVF9PVEEQABILCgdPVEFfQkxFEAESDAoIT1RBX1dJRkkQAkJhChRvcmcubWVzaHRhc3RpYy5wcm90b0ILQWRtaW5Qcm90b3NaImdpdGh1Yi5jb20vbWVzaHRhc3RpYy9nby9nZW5lcmF0ZWSqAhRNZXNodGFzdGljLlByb3RvYnVmc7oCAGIGcHJvdG8z",
+ [
+ file_meshtastic_channel,
+ file_meshtastic_config,
+ file_meshtastic_connection_status,
+ file_meshtastic_device_ui,
+ file_meshtastic_mesh,
+ file_meshtastic_module_config,
+ ],
+);
/**
*
@@ -49,557 +67,616 @@ export type AdminMessage = Message<"meshtastic.AdminMessage"> & {
*
* @generated from oneof meshtastic.AdminMessage.payload_variant
*/
- payloadVariant: {
- /**
- *
- * Send the specified channel in the response to this message
- * NOTE: This field is sent with the channel index + 1 (to ensure we never try to send 'zero' - which protobufs treats as not present)
- *
- * @generated from field: uint32 get_channel_request = 1;
- */
- value: number;
- case: "getChannelRequest";
- } | {
- /**
- *
- * TODO: REPLACE
- *
- * @generated from field: meshtastic.Channel get_channel_response = 2;
- */
- value: Channel;
- case: "getChannelResponse";
- } | {
- /**
- *
- * Send the current owner data in the response to this message.
- *
- * @generated from field: bool get_owner_request = 3;
- */
- value: boolean;
- case: "getOwnerRequest";
- } | {
- /**
- *
- * TODO: REPLACE
- *
- * @generated from field: meshtastic.User get_owner_response = 4;
- */
- value: User;
- case: "getOwnerResponse";
- } | {
- /**
- *
- * Ask for the following config data to be sent
- *
- * @generated from field: meshtastic.AdminMessage.ConfigType get_config_request = 5;
- */
- value: AdminMessage_ConfigType;
- case: "getConfigRequest";
- } | {
- /**
- *
- * Send the current Config in the response to this message.
- *
- * @generated from field: meshtastic.Config get_config_response = 6;
- */
- value: Config;
- case: "getConfigResponse";
- } | {
- /**
- *
- * Ask for the following config data to be sent
- *
- * @generated from field: meshtastic.AdminMessage.ModuleConfigType get_module_config_request = 7;
- */
- value: AdminMessage_ModuleConfigType;
- case: "getModuleConfigRequest";
- } | {
- /**
- *
- * Send the current Config in the response to this message.
- *
- * @generated from field: meshtastic.ModuleConfig get_module_config_response = 8;
- */
- value: ModuleConfig;
- case: "getModuleConfigResponse";
- } | {
- /**
- *
- * Get the Canned Message Module messages in the response to this message.
- *
- * @generated from field: bool get_canned_message_module_messages_request = 10;
- */
- value: boolean;
- case: "getCannedMessageModuleMessagesRequest";
- } | {
- /**
- *
- * Get the Canned Message Module messages in the response to this message.
- *
- * @generated from field: string get_canned_message_module_messages_response = 11;
- */
- value: string;
- case: "getCannedMessageModuleMessagesResponse";
- } | {
- /**
- *
- * Request the node to send device metadata (firmware, protobuf version, etc)
- *
- * @generated from field: bool get_device_metadata_request = 12;
- */
- value: boolean;
- case: "getDeviceMetadataRequest";
- } | {
- /**
- *
- * Device metadata response
- *
- * @generated from field: meshtastic.DeviceMetadata get_device_metadata_response = 13;
- */
- value: DeviceMetadata;
- case: "getDeviceMetadataResponse";
- } | {
- /**
- *
- * Get the Ringtone in the response to this message.
- *
- * @generated from field: bool get_ringtone_request = 14;
- */
- value: boolean;
- case: "getRingtoneRequest";
- } | {
- /**
- *
- * Get the Ringtone in the response to this message.
- *
- * @generated from field: string get_ringtone_response = 15;
- */
- value: string;
- case: "getRingtoneResponse";
- } | {
- /**
- *
- * Request the node to send it's connection status
- *
- * @generated from field: bool get_device_connection_status_request = 16;
- */
- value: boolean;
- case: "getDeviceConnectionStatusRequest";
- } | {
- /**
- *
- * Device connection status response
- *
- * @generated from field: meshtastic.DeviceConnectionStatus get_device_connection_status_response = 17;
- */
- value: DeviceConnectionStatus;
- case: "getDeviceConnectionStatusResponse";
- } | {
- /**
- *
- * Setup a node for licensed amateur (ham) radio operation
- *
- * @generated from field: meshtastic.HamParameters set_ham_mode = 18;
- */
- value: HamParameters;
- case: "setHamMode";
- } | {
- /**
- *
- * Get the mesh's nodes with their available gpio pins for RemoteHardware module use
- *
- * @generated from field: bool get_node_remote_hardware_pins_request = 19;
- */
- value: boolean;
- case: "getNodeRemoteHardwarePinsRequest";
- } | {
- /**
- *
- * Respond with the mesh's nodes with their available gpio pins for RemoteHardware module use
- *
- * @generated from field: meshtastic.NodeRemoteHardwarePinsResponse get_node_remote_hardware_pins_response = 20;
- */
- value: NodeRemoteHardwarePinsResponse;
- case: "getNodeRemoteHardwarePinsResponse";
- } | {
- /**
- *
- * Enter (UF2) DFU mode
- * Only implemented on NRF52 currently
- *
- * @generated from field: bool enter_dfu_mode_request = 21;
- */
- value: boolean;
- case: "enterDfuModeRequest";
- } | {
- /**
- *
- * Delete the file by the specified path from the device
- *
- * @generated from field: string delete_file_request = 22;
- */
- value: string;
- case: "deleteFileRequest";
- } | {
- /**
- *
- * Set zero and offset for scale chips
- *
- * @generated from field: uint32 set_scale = 23;
- */
- value: number;
- case: "setScale";
- } | {
- /**
- *
- * Backup the node's preferences
- *
- * @generated from field: meshtastic.AdminMessage.BackupLocation backup_preferences = 24;
- */
- value: AdminMessage_BackupLocation;
- case: "backupPreferences";
- } | {
- /**
- *
- * Restore the node's preferences
- *
- * @generated from field: meshtastic.AdminMessage.BackupLocation restore_preferences = 25;
- */
- value: AdminMessage_BackupLocation;
- case: "restorePreferences";
- } | {
- /**
- *
- * Remove backups of the node's preferences
- *
- * @generated from field: meshtastic.AdminMessage.BackupLocation remove_backup_preferences = 26;
- */
- value: AdminMessage_BackupLocation;
- case: "removeBackupPreferences";
- } | {
- /**
- *
- * Send an input event to the node.
- * This is used to trigger physical input events like button presses, touch events, etc.
- *
- * @generated from field: meshtastic.AdminMessage.InputEvent send_input_event = 27;
- */
- value: AdminMessage_InputEvent;
- case: "sendInputEvent";
- } | {
- /**
- *
- * Set the owner for this node
- *
- * @generated from field: meshtastic.User set_owner = 32;
- */
- value: User;
- case: "setOwner";
- } | {
- /**
- *
- * Set channels (using the new API).
- * A special channel is the "primary channel".
- * The other records are secondary channels.
- * Note: only one channel can be marked as primary.
- * If the client sets a particular channel to be primary, the previous channel will be set to SECONDARY automatically.
- *
- * @generated from field: meshtastic.Channel set_channel = 33;
- */
- value: Channel;
- case: "setChannel";
- } | {
- /**
- *
- * Set the current Config
- *
- * @generated from field: meshtastic.Config set_config = 34;
- */
- value: Config;
- case: "setConfig";
- } | {
- /**
- *
- * Set the current Config
- *
- * @generated from field: meshtastic.ModuleConfig set_module_config = 35;
- */
- value: ModuleConfig;
- case: "setModuleConfig";
- } | {
- /**
- *
- * Set the Canned Message Module messages text.
- *
- * @generated from field: string set_canned_message_module_messages = 36;
- */
- value: string;
- case: "setCannedMessageModuleMessages";
- } | {
- /**
- *
- * Set the ringtone for ExternalNotification.
- *
- * @generated from field: string set_ringtone_message = 37;
- */
- value: string;
- case: "setRingtoneMessage";
- } | {
- /**
- *
- * Remove the node by the specified node-num from the NodeDB on the device
- *
- * @generated from field: uint32 remove_by_nodenum = 38;
- */
- value: number;
- case: "removeByNodenum";
- } | {
- /**
- *
- * Set specified node-num to be favorited on the NodeDB on the device
- *
- * @generated from field: uint32 set_favorite_node = 39;
- */
- value: number;
- case: "setFavoriteNode";
- } | {
- /**
- *
- * Set specified node-num to be un-favorited on the NodeDB on the device
- *
- * @generated from field: uint32 remove_favorite_node = 40;
- */
- value: number;
- case: "removeFavoriteNode";
- } | {
- /**
- *
- * Set fixed position data on the node and then set the position.fixed_position = true
- *
- * @generated from field: meshtastic.Position set_fixed_position = 41;
- */
- value: Position;
- case: "setFixedPosition";
- } | {
- /**
- *
- * Clear fixed position coordinates and then set position.fixed_position = false
- *
- * @generated from field: bool remove_fixed_position = 42;
- */
- value: boolean;
- case: "removeFixedPosition";
- } | {
- /**
- *
- * Set time only on the node
- * Convenience method to set the time on the node (as Net quality) without any other position data
- *
- * @generated from field: fixed32 set_time_only = 43;
- */
- value: number;
- case: "setTimeOnly";
- } | {
- /**
- *
- * Tell the node to send the stored ui data.
- *
- * @generated from field: bool get_ui_config_request = 44;
- */
- value: boolean;
- case: "getUiConfigRequest";
- } | {
- /**
- *
- * Reply stored device ui data.
- *
- * @generated from field: meshtastic.DeviceUIConfig get_ui_config_response = 45;
- */
- value: DeviceUIConfig;
- case: "getUiConfigResponse";
- } | {
- /**
- *
- * Tell the node to store UI data persistently.
- *
- * @generated from field: meshtastic.DeviceUIConfig store_ui_config = 46;
- */
- value: DeviceUIConfig;
- case: "storeUiConfig";
- } | {
- /**
- *
- * Set specified node-num to be ignored on the NodeDB on the device
- *
- * @generated from field: uint32 set_ignored_node = 47;
- */
- value: number;
- case: "setIgnoredNode";
- } | {
- /**
- *
- * Set specified node-num to be un-ignored on the NodeDB on the device
- *
- * @generated from field: uint32 remove_ignored_node = 48;
- */
- value: number;
- case: "removeIgnoredNode";
- } | {
- /**
- *
- * Set specified node-num to be muted
- *
- * @generated from field: uint32 toggle_muted_node = 49;
- */
- value: number;
- case: "toggleMutedNode";
- } | {
- /**
- *
- * Begins an edit transaction for config, module config, owner, and channel settings changes
- * This will delay the standard *implicit* save to the file system and subsequent reboot behavior until committed (commit_edit_settings)
- *
- * @generated from field: bool begin_edit_settings = 64;
- */
- value: boolean;
- case: "beginEditSettings";
- } | {
- /**
- *
- * Commits an open transaction for any edits made to config, module config, owner, and channel settings
- *
- * @generated from field: bool commit_edit_settings = 65;
- */
- value: boolean;
- case: "commitEditSettings";
- } | {
- /**
- *
- * Add a contact (User) to the nodedb
- *
- * @generated from field: meshtastic.SharedContact add_contact = 66;
- */
- value: SharedContact;
- case: "addContact";
- } | {
- /**
- *
- * Initiate or respond to a key verification request
- *
- * @generated from field: meshtastic.KeyVerificationAdmin key_verification = 67;
- */
- value: KeyVerificationAdmin;
- case: "keyVerification";
- } | {
- /**
- *
- * Tell the node to factory reset config everything; all device state and configuration will be returned to factory defaults and BLE bonds will be cleared.
- *
- * @generated from field: int32 factory_reset_device = 94;
- */
- value: number;
- case: "factoryResetDevice";
- } | {
- /**
- *
- * Tell the node to reboot into the OTA Firmware in this many seconds (or <0 to cancel reboot)
- * Only Implemented for ESP32 Devices. This needs to be issued to send a new main firmware via bluetooth.
- * Deprecated in favor of reboot_ota_mode in 2.7.17
- *
- * @generated from field: int32 reboot_ota_seconds = 95 [deprecated = true];
- * @deprecated
- */
- value: number;
- case: "rebootOtaSeconds";
- } | {
- /**
- *
- * This message is only supported for the simulator Portduino build.
- * If received the simulator will exit successfully.
- *
- * @generated from field: bool exit_simulator = 96;
- */
- value: boolean;
- case: "exitSimulator";
- } | {
- /**
- *
- * Tell the node to reboot in this many seconds (or <0 to cancel reboot)
- *
- * @generated from field: int32 reboot_seconds = 97;
- */
- value: number;
- case: "rebootSeconds";
- } | {
- /**
- *
- * Tell the node to shutdown in this many seconds (or <0 to cancel shutdown)
- *
- * @generated from field: int32 shutdown_seconds = 98;
- */
- value: number;
- case: "shutdownSeconds";
- } | {
- /**
- *
- * Tell the node to factory reset config; all device state and configuration will be returned to factory defaults; BLE bonds will be preserved.
- *
- * @generated from field: int32 factory_reset_config = 99;
- */
- value: number;
- case: "factoryResetConfig";
- } | {
- /**
- *
- * Tell the node to reset the nodedb.
- * When true, favorites are preserved through reset.
- *
- * @generated from field: bool nodedb_reset = 100;
- */
- value: boolean;
- case: "nodedbReset";
- } | {
- /**
- *
- * Tell the node to reset into the OTA Loader
- *
- * @generated from field: meshtastic.AdminMessage.OTAEvent ota_request = 102;
- */
- value: AdminMessage_OTAEvent;
- case: "otaRequest";
- } | {
- /**
- *
- * Parameters and sensor configuration
- *
- * @generated from field: meshtastic.SensorConfig sensor_config = 103;
- */
- value: SensorConfig;
- case: "sensorConfig";
- } | {
- /**
- *
- * Lockdown passphrase delivery / unlock / lock-now command for hardened
- * firmware builds (see MESHTASTIC_LOCKDOWN). Used to provision the
- * passphrase on first boot, unlock encrypted storage on subsequent
- * reboots, re-verify on already-unlocked devices to authorize a new
- * client connection, or immediately re-lock the device.
- *
- * Replaces the earlier scheme that repurposed SecurityConfig.private_key
- * to carry passphrase bytes; that hack is retired.
- *
- * @generated from field: meshtastic.LockdownAuth lockdown_auth = 104;
- */
- value: LockdownAuth;
- case: "lockdownAuth";
- } | { case: undefined; value?: undefined };
+ payloadVariant:
+ | {
+ /**
+ *
+ * Send the specified channel in the response to this message
+ * NOTE: This field is sent with the channel index + 1 (to ensure we never try to send 'zero' - which protobufs treats as not present)
+ *
+ * @generated from field: uint32 get_channel_request = 1;
+ */
+ value: number;
+ case: "getChannelRequest";
+ }
+ | {
+ /**
+ *
+ * TODO: REPLACE
+ *
+ * @generated from field: meshtastic.Channel get_channel_response = 2;
+ */
+ value: Channel;
+ case: "getChannelResponse";
+ }
+ | {
+ /**
+ *
+ * Send the current owner data in the response to this message.
+ *
+ * @generated from field: bool get_owner_request = 3;
+ */
+ value: boolean;
+ case: "getOwnerRequest";
+ }
+ | {
+ /**
+ *
+ * TODO: REPLACE
+ *
+ * @generated from field: meshtastic.User get_owner_response = 4;
+ */
+ value: User;
+ case: "getOwnerResponse";
+ }
+ | {
+ /**
+ *
+ * Ask for the following config data to be sent
+ *
+ * @generated from field: meshtastic.AdminMessage.ConfigType get_config_request = 5;
+ */
+ value: AdminMessage_ConfigType;
+ case: "getConfigRequest";
+ }
+ | {
+ /**
+ *
+ * Send the current Config in the response to this message.
+ *
+ * @generated from field: meshtastic.Config get_config_response = 6;
+ */
+ value: Config;
+ case: "getConfigResponse";
+ }
+ | {
+ /**
+ *
+ * Ask for the following config data to be sent
+ *
+ * @generated from field: meshtastic.AdminMessage.ModuleConfigType get_module_config_request = 7;
+ */
+ value: AdminMessage_ModuleConfigType;
+ case: "getModuleConfigRequest";
+ }
+ | {
+ /**
+ *
+ * Send the current Config in the response to this message.
+ *
+ * @generated from field: meshtastic.ModuleConfig get_module_config_response = 8;
+ */
+ value: ModuleConfig;
+ case: "getModuleConfigResponse";
+ }
+ | {
+ /**
+ *
+ * Get the Canned Message Module messages in the response to this message.
+ *
+ * @generated from field: bool get_canned_message_module_messages_request = 10;
+ */
+ value: boolean;
+ case: "getCannedMessageModuleMessagesRequest";
+ }
+ | {
+ /**
+ *
+ * Get the Canned Message Module messages in the response to this message.
+ *
+ * @generated from field: string get_canned_message_module_messages_response = 11;
+ */
+ value: string;
+ case: "getCannedMessageModuleMessagesResponse";
+ }
+ | {
+ /**
+ *
+ * Request the node to send device metadata (firmware, protobuf version, etc)
+ *
+ * @generated from field: bool get_device_metadata_request = 12;
+ */
+ value: boolean;
+ case: "getDeviceMetadataRequest";
+ }
+ | {
+ /**
+ *
+ * Device metadata response
+ *
+ * @generated from field: meshtastic.DeviceMetadata get_device_metadata_response = 13;
+ */
+ value: DeviceMetadata;
+ case: "getDeviceMetadataResponse";
+ }
+ | {
+ /**
+ *
+ * Get the Ringtone in the response to this message.
+ *
+ * @generated from field: bool get_ringtone_request = 14;
+ */
+ value: boolean;
+ case: "getRingtoneRequest";
+ }
+ | {
+ /**
+ *
+ * Get the Ringtone in the response to this message.
+ *
+ * @generated from field: string get_ringtone_response = 15;
+ */
+ value: string;
+ case: "getRingtoneResponse";
+ }
+ | {
+ /**
+ *
+ * Request the node to send it's connection status
+ *
+ * @generated from field: bool get_device_connection_status_request = 16;
+ */
+ value: boolean;
+ case: "getDeviceConnectionStatusRequest";
+ }
+ | {
+ /**
+ *
+ * Device connection status response
+ *
+ * @generated from field: meshtastic.DeviceConnectionStatus get_device_connection_status_response = 17;
+ */
+ value: DeviceConnectionStatus;
+ case: "getDeviceConnectionStatusResponse";
+ }
+ | {
+ /**
+ *
+ * Setup a node for licensed amateur (ham) radio operation
+ *
+ * @generated from field: meshtastic.HamParameters set_ham_mode = 18;
+ */
+ value: HamParameters;
+ case: "setHamMode";
+ }
+ | {
+ /**
+ *
+ * Get the mesh's nodes with their available gpio pins for RemoteHardware module use
+ *
+ * @generated from field: bool get_node_remote_hardware_pins_request = 19;
+ */
+ value: boolean;
+ case: "getNodeRemoteHardwarePinsRequest";
+ }
+ | {
+ /**
+ *
+ * Respond with the mesh's nodes with their available gpio pins for RemoteHardware module use
+ *
+ * @generated from field: meshtastic.NodeRemoteHardwarePinsResponse get_node_remote_hardware_pins_response = 20;
+ */
+ value: NodeRemoteHardwarePinsResponse;
+ case: "getNodeRemoteHardwarePinsResponse";
+ }
+ | {
+ /**
+ *
+ * Enter (UF2) DFU mode
+ * Only implemented on NRF52 currently
+ *
+ * @generated from field: bool enter_dfu_mode_request = 21;
+ */
+ value: boolean;
+ case: "enterDfuModeRequest";
+ }
+ | {
+ /**
+ *
+ * Delete the file by the specified path from the device
+ *
+ * @generated from field: string delete_file_request = 22;
+ */
+ value: string;
+ case: "deleteFileRequest";
+ }
+ | {
+ /**
+ *
+ * Set zero and offset for scale chips
+ *
+ * @generated from field: uint32 set_scale = 23;
+ */
+ value: number;
+ case: "setScale";
+ }
+ | {
+ /**
+ *
+ * Backup the node's preferences
+ *
+ * @generated from field: meshtastic.AdminMessage.BackupLocation backup_preferences = 24;
+ */
+ value: AdminMessage_BackupLocation;
+ case: "backupPreferences";
+ }
+ | {
+ /**
+ *
+ * Restore the node's preferences
+ *
+ * @generated from field: meshtastic.AdminMessage.BackupLocation restore_preferences = 25;
+ */
+ value: AdminMessage_BackupLocation;
+ case: "restorePreferences";
+ }
+ | {
+ /**
+ *
+ * Remove backups of the node's preferences
+ *
+ * @generated from field: meshtastic.AdminMessage.BackupLocation remove_backup_preferences = 26;
+ */
+ value: AdminMessage_BackupLocation;
+ case: "removeBackupPreferences";
+ }
+ | {
+ /**
+ *
+ * Send an input event to the node.
+ * This is used to trigger physical input events like button presses, touch events, etc.
+ *
+ * @generated from field: meshtastic.AdminMessage.InputEvent send_input_event = 27;
+ */
+ value: AdminMessage_InputEvent;
+ case: "sendInputEvent";
+ }
+ | {
+ /**
+ *
+ * Set the owner for this node
+ *
+ * @generated from field: meshtastic.User set_owner = 32;
+ */
+ value: User;
+ case: "setOwner";
+ }
+ | {
+ /**
+ *
+ * Set channels (using the new API).
+ * A special channel is the "primary channel".
+ * The other records are secondary channels.
+ * Note: only one channel can be marked as primary.
+ * If the client sets a particular channel to be primary, the previous channel will be set to SECONDARY automatically.
+ *
+ * @generated from field: meshtastic.Channel set_channel = 33;
+ */
+ value: Channel;
+ case: "setChannel";
+ }
+ | {
+ /**
+ *
+ * Set the current Config
+ *
+ * @generated from field: meshtastic.Config set_config = 34;
+ */
+ value: Config;
+ case: "setConfig";
+ }
+ | {
+ /**
+ *
+ * Set the current Config
+ *
+ * @generated from field: meshtastic.ModuleConfig set_module_config = 35;
+ */
+ value: ModuleConfig;
+ case: "setModuleConfig";
+ }
+ | {
+ /**
+ *
+ * Set the Canned Message Module messages text.
+ *
+ * @generated from field: string set_canned_message_module_messages = 36;
+ */
+ value: string;
+ case: "setCannedMessageModuleMessages";
+ }
+ | {
+ /**
+ *
+ * Set the ringtone for ExternalNotification.
+ *
+ * @generated from field: string set_ringtone_message = 37;
+ */
+ value: string;
+ case: "setRingtoneMessage";
+ }
+ | {
+ /**
+ *
+ * Remove the node by the specified node-num from the NodeDB on the device
+ *
+ * @generated from field: uint32 remove_by_nodenum = 38;
+ */
+ value: number;
+ case: "removeByNodenum";
+ }
+ | {
+ /**
+ *
+ * Set specified node-num to be favorited on the NodeDB on the device
+ *
+ * @generated from field: uint32 set_favorite_node = 39;
+ */
+ value: number;
+ case: "setFavoriteNode";
+ }
+ | {
+ /**
+ *
+ * Set specified node-num to be un-favorited on the NodeDB on the device
+ *
+ * @generated from field: uint32 remove_favorite_node = 40;
+ */
+ value: number;
+ case: "removeFavoriteNode";
+ }
+ | {
+ /**
+ *
+ * Set fixed position data on the node and then set the position.fixed_position = true
+ *
+ * @generated from field: meshtastic.Position set_fixed_position = 41;
+ */
+ value: Position;
+ case: "setFixedPosition";
+ }
+ | {
+ /**
+ *
+ * Clear fixed position coordinates and then set position.fixed_position = false
+ *
+ * @generated from field: bool remove_fixed_position = 42;
+ */
+ value: boolean;
+ case: "removeFixedPosition";
+ }
+ | {
+ /**
+ *
+ * Set time only on the node
+ * Convenience method to set the time on the node (as Net quality) without any other position data
+ *
+ * @generated from field: fixed32 set_time_only = 43;
+ */
+ value: number;
+ case: "setTimeOnly";
+ }
+ | {
+ /**
+ *
+ * Tell the node to send the stored ui data.
+ *
+ * @generated from field: bool get_ui_config_request = 44;
+ */
+ value: boolean;
+ case: "getUiConfigRequest";
+ }
+ | {
+ /**
+ *
+ * Reply stored device ui data.
+ *
+ * @generated from field: meshtastic.DeviceUIConfig get_ui_config_response = 45;
+ */
+ value: DeviceUIConfig;
+ case: "getUiConfigResponse";
+ }
+ | {
+ /**
+ *
+ * Tell the node to store UI data persistently.
+ *
+ * @generated from field: meshtastic.DeviceUIConfig store_ui_config = 46;
+ */
+ value: DeviceUIConfig;
+ case: "storeUiConfig";
+ }
+ | {
+ /**
+ *
+ * Set specified node-num to be ignored on the NodeDB on the device
+ *
+ * @generated from field: uint32 set_ignored_node = 47;
+ */
+ value: number;
+ case: "setIgnoredNode";
+ }
+ | {
+ /**
+ *
+ * Set specified node-num to be un-ignored on the NodeDB on the device
+ *
+ * @generated from field: uint32 remove_ignored_node = 48;
+ */
+ value: number;
+ case: "removeIgnoredNode";
+ }
+ | {
+ /**
+ *
+ * Set specified node-num to be muted
+ *
+ * @generated from field: uint32 toggle_muted_node = 49;
+ */
+ value: number;
+ case: "toggleMutedNode";
+ }
+ | {
+ /**
+ *
+ * Begins an edit transaction for config, module config, owner, and channel settings changes
+ * This will delay the standard *implicit* save to the file system and subsequent reboot behavior until committed (commit_edit_settings)
+ *
+ * @generated from field: bool begin_edit_settings = 64;
+ */
+ value: boolean;
+ case: "beginEditSettings";
+ }
+ | {
+ /**
+ *
+ * Commits an open transaction for any edits made to config, module config, owner, and channel settings
+ *
+ * @generated from field: bool commit_edit_settings = 65;
+ */
+ value: boolean;
+ case: "commitEditSettings";
+ }
+ | {
+ /**
+ *
+ * Add a contact (User) to the nodedb
+ *
+ * @generated from field: meshtastic.SharedContact add_contact = 66;
+ */
+ value: SharedContact;
+ case: "addContact";
+ }
+ | {
+ /**
+ *
+ * Initiate or respond to a key verification request
+ *
+ * @generated from field: meshtastic.KeyVerificationAdmin key_verification = 67;
+ */
+ value: KeyVerificationAdmin;
+ case: "keyVerification";
+ }
+ | {
+ /**
+ *
+ * Tell the node to factory reset config everything; all device state and configuration will be returned to factory defaults and BLE bonds will be cleared.
+ *
+ * @generated from field: int32 factory_reset_device = 94;
+ */
+ value: number;
+ case: "factoryResetDevice";
+ }
+ | {
+ /**
+ *
+ * Tell the node to reboot into the OTA Firmware in this many seconds (or <0 to cancel reboot)
+ * Only Implemented for ESP32 Devices. This needs to be issued to send a new main firmware via bluetooth.
+ * Deprecated in favor of reboot_ota_mode in 2.7.17
+ *
+ * @generated from field: int32 reboot_ota_seconds = 95 [deprecated = true];
+ * @deprecated
+ */
+ value: number;
+ case: "rebootOtaSeconds";
+ }
+ | {
+ /**
+ *
+ * This message is only supported for the simulator Portduino build.
+ * If received the simulator will exit successfully.
+ *
+ * @generated from field: bool exit_simulator = 96;
+ */
+ value: boolean;
+ case: "exitSimulator";
+ }
+ | {
+ /**
+ *
+ * Tell the node to reboot in this many seconds (or <0 to cancel reboot)
+ *
+ * @generated from field: int32 reboot_seconds = 97;
+ */
+ value: number;
+ case: "rebootSeconds";
+ }
+ | {
+ /**
+ *
+ * Tell the node to shutdown in this many seconds (or <0 to cancel shutdown)
+ *
+ * @generated from field: int32 shutdown_seconds = 98;
+ */
+ value: number;
+ case: "shutdownSeconds";
+ }
+ | {
+ /**
+ *
+ * Tell the node to factory reset config; all device state and configuration will be returned to factory defaults; BLE bonds will be preserved.
+ *
+ * @generated from field: int32 factory_reset_config = 99;
+ */
+ value: number;
+ case: "factoryResetConfig";
+ }
+ | {
+ /**
+ *
+ * Tell the node to reset the nodedb.
+ * When true, favorites are preserved through reset.
+ *
+ * @generated from field: bool nodedb_reset = 100;
+ */
+ value: boolean;
+ case: "nodedbReset";
+ }
+ | {
+ /**
+ *
+ * Tell the node to reset into the OTA Loader
+ *
+ * @generated from field: meshtastic.AdminMessage.OTAEvent ota_request = 102;
+ */
+ value: AdminMessage_OTAEvent;
+ case: "otaRequest";
+ }
+ | {
+ /**
+ *
+ * Parameters and sensor configuration
+ *
+ * @generated from field: meshtastic.SensorConfig sensor_config = 103;
+ */
+ value: SensorConfig;
+ case: "sensorConfig";
+ }
+ | {
+ /**
+ *
+ * Lockdown passphrase delivery / unlock / lock-now command for hardened
+ * firmware builds (see MESHTASTIC_LOCKDOWN). Used to provision the
+ * passphrase on first boot, unlock encrypted storage on subsequent
+ * reboots, re-verify on already-unlocked devices to authorize a new
+ * client connection, or immediately re-lock the device.
+ *
+ * Replaces the earlier scheme that repurposed SecurityConfig.private_key
+ * to carry passphrase bytes; that hack is retired.
+ *
+ * @generated from field: meshtastic.LockdownAuth lockdown_auth = 104;
+ */
+ value: LockdownAuth;
+ case: "lockdownAuth";
+ }
+ | { case: undefined; value?: undefined };
};
/**
* Describes the message meshtastic.AdminMessage.
* Use `create(AdminMessageSchema)` to create a new message.
*/
-export const AdminMessageSchema: GenMessage = /*@__PURE__*/
+export const AdminMessageSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_admin, 0);
/**
@@ -608,45 +685,46 @@ export const AdminMessageSchema: GenMessage = /*@__PURE__*/
*
* @generated from message meshtastic.AdminMessage.InputEvent
*/
-export type AdminMessage_InputEvent = Message<"meshtastic.AdminMessage.InputEvent"> & {
- /**
- *
- * The input event code
- *
- * @generated from field: uint32 event_code = 1;
- */
- eventCode: number;
+export type AdminMessage_InputEvent =
+ Message<"meshtastic.AdminMessage.InputEvent"> & {
+ /**
+ *
+ * The input event code
+ *
+ * @generated from field: uint32 event_code = 1;
+ */
+ eventCode: number;
- /**
- *
- * Keyboard character code
- *
- * @generated from field: uint32 kb_char = 2;
- */
- kbChar: number;
+ /**
+ *
+ * Keyboard character code
+ *
+ * @generated from field: uint32 kb_char = 2;
+ */
+ kbChar: number;
- /**
- *
- * The touch X coordinate
- *
- * @generated from field: uint32 touch_x = 3;
- */
- touchX: number;
+ /**
+ *
+ * The touch X coordinate
+ *
+ * @generated from field: uint32 touch_x = 3;
+ */
+ touchX: number;
- /**
- *
- * The touch Y coordinate
- *
- * @generated from field: uint32 touch_y = 4;
- */
- touchY: number;
-};
+ /**
+ *
+ * The touch Y coordinate
+ *
+ * @generated from field: uint32 touch_y = 4;
+ */
+ touchY: number;
+ };
/**
* Describes the message meshtastic.AdminMessage.InputEvent.
* Use `create(AdminMessage_InputEventSchema)` to create a new message.
*/
-export const AdminMessage_InputEventSchema: GenMessage = /*@__PURE__*/
+export const AdminMessage_InputEventSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_admin, 0, 0);
/**
@@ -656,30 +734,31 @@ export const AdminMessage_InputEventSchema: GenMessage
*
* @generated from message meshtastic.AdminMessage.OTAEvent
*/
-export type AdminMessage_OTAEvent = Message<"meshtastic.AdminMessage.OTAEvent"> & {
- /**
- *
- * Tell the node to reboot into OTA mode for firmware update via BLE or WiFi (ESP32 only for now)
- *
- * @generated from field: meshtastic.OTAMode reboot_ota_mode = 1;
- */
- rebootOtaMode: OTAMode;
+export type AdminMessage_OTAEvent =
+ Message<"meshtastic.AdminMessage.OTAEvent"> & {
+ /**
+ *
+ * Tell the node to reboot into OTA mode for firmware update via BLE or WiFi (ESP32 only for now)
+ *
+ * @generated from field: meshtastic.OTAMode reboot_ota_mode = 1;
+ */
+ rebootOtaMode: OTAMode;
- /**
- *
- * A 32 byte hash of the OTA firmware.
- * Used to verify the integrity of the firmware before applying an update.
- *
- * @generated from field: bytes ota_hash = 2;
- */
- otaHash: Uint8Array;
-};
+ /**
+ *
+ * A 32 byte hash of the OTA firmware.
+ * Used to verify the integrity of the firmware before applying an update.
+ *
+ * @generated from field: bytes ota_hash = 2;
+ */
+ otaHash: Uint8Array;
+ };
/**
* Describes the message meshtastic.AdminMessage.OTAEvent.
* Use `create(AdminMessage_OTAEventSchema)` to create a new message.
*/
-export const AdminMessage_OTAEventSchema: GenMessage = /*@__PURE__*/
+export const AdminMessage_OTAEventSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_admin, 0, 1);
/**
@@ -773,7 +852,7 @@ export enum AdminMessage_ConfigType {
/**
* Describes the enum meshtastic.AdminMessage.ConfigType.
*/
-export const AdminMessage_ConfigTypeSchema: GenEnum = /*@__PURE__*/
+export const AdminMessage_ConfigTypeSchema: GenEnum /*@__PURE__*/ =
enumDesc(file_meshtastic_admin, 0, 0);
/**
@@ -915,7 +994,7 @@ export enum AdminMessage_ModuleConfigType {
/**
* Describes the enum meshtastic.AdminMessage.ModuleConfigType.
*/
-export const AdminMessage_ModuleConfigTypeSchema: GenEnum = /*@__PURE__*/
+export const AdminMessage_ModuleConfigTypeSchema: GenEnum /*@__PURE__*/ =
enumDesc(file_meshtastic_admin, 0, 1);
/**
@@ -942,7 +1021,7 @@ export enum AdminMessage_BackupLocation {
/**
* Describes the enum meshtastic.AdminMessage.BackupLocation.
*/
-export const AdminMessage_BackupLocationSchema: GenEnum = /*@__PURE__*/
+export const AdminMessage_BackupLocationSchema: GenEnum /*@__PURE__*/ =
enumDesc(file_meshtastic_admin, 0, 2);
/**
@@ -1080,7 +1159,7 @@ export type LockdownAuth = Message<"meshtastic.LockdownAuth"> & {
* Describes the message meshtastic.LockdownAuth.
* Use `create(LockdownAuthSchema)` to create a new message.
*/
-export const LockdownAuthSchema: GenMessage = /*@__PURE__*/
+export const LockdownAuthSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_admin, 1);
/**
@@ -1138,7 +1217,7 @@ export type HamParameters = Message<"meshtastic.HamParameters"> & {
* Describes the message meshtastic.HamParameters.
* Use `create(HamParametersSchema)` to create a new message.
*/
-export const HamParametersSchema: GenMessage = /*@__PURE__*/
+export const HamParametersSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_admin, 2);
/**
@@ -1147,21 +1226,22 @@ export const HamParametersSchema: GenMessage = /*@__PURE__*/
*
* @generated from message meshtastic.NodeRemoteHardwarePinsResponse
*/
-export type NodeRemoteHardwarePinsResponse = Message<"meshtastic.NodeRemoteHardwarePinsResponse"> & {
- /**
- *
- * Nodes and their respective remote hardware GPIO pins
- *
- * @generated from field: repeated meshtastic.NodeRemoteHardwarePin node_remote_hardware_pins = 1;
- */
- nodeRemoteHardwarePins: NodeRemoteHardwarePin[];
-};
+export type NodeRemoteHardwarePinsResponse =
+ Message<"meshtastic.NodeRemoteHardwarePinsResponse"> & {
+ /**
+ *
+ * Nodes and their respective remote hardware GPIO pins
+ *
+ * @generated from field: repeated meshtastic.NodeRemoteHardwarePin node_remote_hardware_pins = 1;
+ */
+ nodeRemoteHardwarePins: NodeRemoteHardwarePin[];
+ };
/**
* Describes the message meshtastic.NodeRemoteHardwarePinsResponse.
* Use `create(NodeRemoteHardwarePinsResponseSchema)` to create a new message.
*/
-export const NodeRemoteHardwarePinsResponseSchema: GenMessage = /*@__PURE__*/
+export const NodeRemoteHardwarePinsResponseSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_admin, 3);
/**
@@ -1205,7 +1285,7 @@ export type SharedContact = Message<"meshtastic.SharedContact"> & {
* Describes the message meshtastic.SharedContact.
* Use `create(SharedContactSchema)` to create a new message.
*/
-export const SharedContactSchema: GenMessage = /*@__PURE__*/
+export const SharedContactSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_admin, 4);
/**
@@ -1214,42 +1294,43 @@ export const SharedContactSchema: GenMessage = /*@__PURE__*/
*
* @generated from message meshtastic.KeyVerificationAdmin
*/
-export type KeyVerificationAdmin = Message<"meshtastic.KeyVerificationAdmin"> & {
- /**
- * @generated from field: meshtastic.KeyVerificationAdmin.MessageType message_type = 1;
- */
- messageType: KeyVerificationAdmin_MessageType;
+export type KeyVerificationAdmin =
+ Message<"meshtastic.KeyVerificationAdmin"> & {
+ /**
+ * @generated from field: meshtastic.KeyVerificationAdmin.MessageType message_type = 1;
+ */
+ messageType: KeyVerificationAdmin_MessageType;
- /**
- *
- * The nodenum we're requesting
- *
- * @generated from field: uint32 remote_nodenum = 2;
- */
- remoteNodenum: number;
+ /**
+ *
+ * The nodenum we're requesting
+ *
+ * @generated from field: uint32 remote_nodenum = 2;
+ */
+ remoteNodenum: number;
- /**
- *
- * The nonce is used to track the connection
- *
- * @generated from field: uint64 nonce = 3;
- */
- nonce: bigint;
+ /**
+ *
+ * The nonce is used to track the connection
+ *
+ * @generated from field: uint64 nonce = 3;
+ */
+ nonce: bigint;
- /**
- *
- * The 4 digit code generated by the remote node, and communicated outside the mesh
- *
- * @generated from field: optional uint32 security_number = 4;
- */
- securityNumber?: number | undefined;
-};
+ /**
+ *
+ * The 4 digit code generated by the remote node, and communicated outside the mesh
+ *
+ * @generated from field: optional uint32 security_number = 4;
+ */
+ securityNumber?: number | undefined;
+ };
/**
* Describes the message meshtastic.KeyVerificationAdmin.
* Use `create(KeyVerificationAdminSchema)` to create a new message.
*/
-export const KeyVerificationAdminSchema: GenMessage = /*@__PURE__*/
+export const KeyVerificationAdminSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_admin, 5);
/**
@@ -1296,7 +1377,7 @@ export enum KeyVerificationAdmin_MessageType {
/**
* Describes the enum meshtastic.KeyVerificationAdmin.MessageType.
*/
-export const KeyVerificationAdmin_MessageTypeSchema: GenEnum = /*@__PURE__*/
+export const KeyVerificationAdmin_MessageTypeSchema: GenEnum /*@__PURE__*/ =
enumDesc(file_meshtastic_admin, 5, 0);
/**
@@ -1340,7 +1421,7 @@ export type SensorConfig = Message<"meshtastic.SensorConfig"> & {
* Describes the message meshtastic.SensorConfig.
* Use `create(SensorConfigSchema)` to create a new message.
*/
-export const SensorConfigSchema: GenMessage = /*@__PURE__*/
+export const SensorConfigSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_admin, 6);
/**
@@ -1408,7 +1489,7 @@ export type SCD4X_config = Message<"meshtastic.SCD4X_config"> & {
* Describes the message meshtastic.SCD4X_config.
* Use `create(SCD4X_configSchema)` to create a new message.
*/
-export const SCD4X_configSchema: GenMessage = /*@__PURE__*/
+export const SCD4X_configSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_admin, 7);
/**
@@ -1436,7 +1517,7 @@ export type SEN5X_config = Message<"meshtastic.SEN5X_config"> & {
* Describes the message meshtastic.SEN5X_config.
* Use `create(SEN5X_configSchema)` to create a new message.
*/
-export const SEN5X_configSchema: GenMessage = /*@__PURE__*/
+export const SEN5X_configSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_admin, 8);
/**
@@ -1496,7 +1577,7 @@ export type SCD30_config = Message<"meshtastic.SCD30_config"> & {
* Describes the message meshtastic.SCD30_config.
* Use `create(SCD30_configSchema)` to create a new message.
*/
-export const SCD30_configSchema: GenMessage = /*@__PURE__*/
+export const SCD30_configSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_admin, 9);
/**
@@ -1516,7 +1597,7 @@ export type SHTXX_config = Message<"meshtastic.SHTXX_config"> & {
* Describes the message meshtastic.SHTXX_config.
* Use `create(SHTXX_configSchema)` to create a new message.
*/
-export const SHTXX_configSchema: GenMessage = /*@__PURE__*/
+export const SHTXX_configSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_admin, 10);
/**
@@ -1554,6 +1635,7 @@ export enum OTAMode {
/**
* Describes the enum meshtastic.OTAMode.
*/
-export const OTAModeSchema: GenEnum = /*@__PURE__*/
- enumDesc(file_meshtastic_admin, 0);
-
+export const OTAModeSchema: GenEnum /*@__PURE__*/ = enumDesc(
+ file_meshtastic_admin,
+ 0,
+);
diff --git a/packages/protobufs/packages/ts/dist/meshtastic/apponly_pb.ts b/packages/protobufs/packages/ts/dist/meshtastic/apponly_pb.ts
index 2b3aee646..752018a23 100644
--- a/packages/protobufs/packages/ts/dist/meshtastic/apponly_pb.ts
+++ b/packages/protobufs/packages/ts/dist/meshtastic/apponly_pb.ts
@@ -1,4 +1,4 @@
-// @generated by protoc-gen-es v2.12.0 with parameter "target=ts"
+// @generated by protoc-gen-es v2.12.1 with parameter "target=ts"
// @generated from file meshtastic/apponly.proto (package meshtastic, syntax proto3)
/* eslint-disable */
@@ -13,8 +13,10 @@ import type { Message } from "@bufbuild/protobuf";
/**
* Describes the file meshtastic/apponly.proto.
*/
-export const file_meshtastic_apponly: GenFile = /*@__PURE__*/
- fileDesc("ChhtZXNodGFzdGljL2FwcG9ubHkucHJvdG8SCm1lc2h0YXN0aWMibwoKQ2hhbm5lbFNldBItCghzZXR0aW5ncxgBIAMoCzIbLm1lc2h0YXN0aWMuQ2hhbm5lbFNldHRpbmdzEjIKC2xvcmFfY29uZmlnGAIgASgLMh0ubWVzaHRhc3RpYy5Db25maWcuTG9SYUNvbmZpZ0JjChRvcmcubWVzaHRhc3RpYy5wcm90b0INQXBwT25seVByb3Rvc1oiZ2l0aHViLmNvbS9tZXNodGFzdGljL2dvL2dlbmVyYXRlZKoCFE1lc2h0YXN0aWMuUHJvdG9idWZzugIAYgZwcm90bzM", [file_meshtastic_channel, file_meshtastic_config]);
+export const file_meshtastic_apponly: GenFile /*@__PURE__*/ = fileDesc(
+ "ChhtZXNodGFzdGljL2FwcG9ubHkucHJvdG8SCm1lc2h0YXN0aWMibwoKQ2hhbm5lbFNldBItCghzZXR0aW5ncxgBIAMoCzIbLm1lc2h0YXN0aWMuQ2hhbm5lbFNldHRpbmdzEjIKC2xvcmFfY29uZmlnGAIgASgLMh0ubWVzaHRhc3RpYy5Db25maWcuTG9SYUNvbmZpZ0JjChRvcmcubWVzaHRhc3RpYy5wcm90b0INQXBwT25seVByb3Rvc1oiZ2l0aHViLmNvbS9tZXNodGFzdGljL2dvL2dlbmVyYXRlZKoCFE1lc2h0YXN0aWMuUHJvdG9idWZzugIAYgZwcm90bzM",
+ [file_meshtastic_channel, file_meshtastic_config],
+);
/**
*
@@ -48,6 +50,5 @@ export type ChannelSet = Message<"meshtastic.ChannelSet"> & {
* Describes the message meshtastic.ChannelSet.
* Use `create(ChannelSetSchema)` to create a new message.
*/
-export const ChannelSetSchema: GenMessage = /*@__PURE__*/
+export const ChannelSetSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_apponly, 0);
-
diff --git a/packages/protobufs/packages/ts/dist/meshtastic/atak_pb.ts b/packages/protobufs/packages/ts/dist/meshtastic/atak_pb.ts
index b27b15b11..5426dfc83 100644
--- a/packages/protobufs/packages/ts/dist/meshtastic/atak_pb.ts
+++ b/packages/protobufs/packages/ts/dist/meshtastic/atak_pb.ts
@@ -1,18 +1,23 @@
-// @generated by protoc-gen-es v2.12.0 with parameter "target=ts"
+// @generated by protoc-gen-es v2.12.1 with parameter "target=ts"
// @generated from file meshtastic/atak.proto (package meshtastic, syntax proto3)
/* eslint-disable */
-// trunk-ignore(buf-lint/PACKAGE_DIRECTORY_MATCH)
+// trunk-ignore(buf-lint/PACKAGE_DIRECTORY_MATCH)
-import type { GenEnum, GenFile, GenMessage } from "@bufbuild/protobuf/codegenv2";
+import type {
+ GenEnum,
+ GenFile,
+ GenMessage,
+} from "@bufbuild/protobuf/codegenv2";
import { enumDesc, fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2";
import type { Message } from "@bufbuild/protobuf";
/**
* Describes the file meshtastic/atak.proto.
*/
-export const file_meshtastic_atak: GenFile = /*@__PURE__*/
- fileDesc("ChVtZXNodGFzdGljL2F0YWsucHJvdG8SCm1lc2h0YXN0aWMi+AEKCVRBS1BhY2tldBIVCg1pc19jb21wcmVzc2VkGAEgASgIEiQKB2NvbnRhY3QYAiABKAsyEy5tZXNodGFzdGljLkNvbnRhY3QSIAoFZ3JvdXAYAyABKAsyES5tZXNodGFzdGljLkdyb3VwEiIKBnN0YXR1cxgEIAEoCzISLm1lc2h0YXN0aWMuU3RhdHVzEh4KA3BsaRgFIAEoCzIPLm1lc2h0YXN0aWMuUExJSAASIwoEY2hhdBgGIAEoCzITLm1lc2h0YXN0aWMuR2VvQ2hhdEgAEhAKBmRldGFpbBgHIAEoDEgAQhEKD3BheWxvYWRfdmFyaWFudCL0AgoHR2VvQ2hhdBIPCgdtZXNzYWdlGAEgASgJEg8KAnRvGAIgASgJSACIAQESGAoLdG9fY2FsbHNpZ24YAyABKAlIAYgBARIXCg9yZWNlaXB0X2Zvcl91aWQYBCABKAkSNQoMcmVjZWlwdF90eXBlGAUgASgOMh8ubWVzaHRhc3RpYy5HZW9DaGF0LlJlY2VpcHRUeXBlEhEKBGxhbmcYBiABKAlIAogBARIUCgdyb29tX2lkGAcgASgJSAOIAQESHQoQdm9pY2VfcHJvZmlsZV9pZBgIIAEoCUgEiAEBIlQKC1JlY2VpcHRUeXBlEhQKEFJlY2VpcHRUeXBlX05vbmUQABIZChVSZWNlaXB0VHlwZV9EZWxpdmVyZWQQARIUChBSZWNlaXB0VHlwZV9SZWFkEAJCBQoDX3RvQg4KDF90b19jYWxsc2lnbkIHCgVfbGFuZ0IKCghfcm9vbV9pZEITChFfdm9pY2VfcHJvZmlsZV9pZCJNCgVHcm91cBIkCgRyb2xlGAEgASgOMhYubWVzaHRhc3RpYy5NZW1iZXJSb2xlEh4KBHRlYW0YAiABKA4yEC5tZXNodGFzdGljLlRlYW0iGQoGU3RhdHVzEg8KB2JhdHRlcnkYASABKA0iNAoHQ29udGFjdBIQCghjYWxsc2lnbhgBIAEoCRIXCg9kZXZpY2VfY2FsbHNpZ24YAiABKAkiXwoDUExJEhIKCmxhdGl0dWRlX2kYASABKA8SEwoLbG9uZ2l0dWRlX2kYAiABKA8SEAoIYWx0aXR1ZGUYAyABKAUSDQoFc3BlZWQYBCABKA0SDgoGY291cnNlGAUgASgNIrABCg1BaXJjcmFmdFRyYWNrEgwKBGljYW8YASABKAkSFAoMcmVnaXN0cmF0aW9uGAIgASgJEg4KBmZsaWdodBgDIAEoCRIVCg1haXJjcmFmdF90eXBlGAQgASgJEg4KBnNxdWF3axgFIAEoDRIQCghjYXRlZ29yeRgGIAEoCRIQCghyc3NpX3gxMBgHIAEoERILCgNncHMYCCABKAgSEwoLY290X2hvc3RfaWQYCSABKAkiNwoLQ290R2VvUG9pbnQSEwoLbGF0X2RlbHRhX2kYASABKBESEwoLbG9uX2RlbHRhX2kYAiABKBEi3AYKCkRyYXduU2hhcGUSKQoEa2luZBgBIAEoDjIbLm1lc2h0YXN0aWMuRHJhd25TaGFwZS5LaW5kEi8KBXN0eWxlGAIgASgOMiAubWVzaHRhc3RpYy5EcmF3blNoYXBlLlN0eWxlTW9kZRIQCghtYWpvcl9jbRgDIAEoDRIQCghtaW5vcl9jbRgEIAEoDRIRCglhbmdsZV9kZWcYBSABKA0SJgoMc3Ryb2tlX2NvbG9yGAYgASgOMhAubWVzaHRhc3RpYy5UZWFtEhMKC3N0cm9rZV9hcmdiGAcgASgHEhkKEXN0cm9rZV93ZWlnaHRfeDEwGAggASgNEiQKCmZpbGxfY29sb3IYCSABKA4yEC5tZXNodGFzdGljLlRlYW0SEQoJZmlsbF9hcmdiGAogASgHEhEKCWxhYmVsc19vbhgLIAEoCBIZChF2ZXJ0ZXhfbGF0X2RlbHRhcxgSIAMoERIZChF2ZXJ0ZXhfbG9uX2RlbHRhcxgTIAMoERIRCgl0cnVuY2F0ZWQYDSABKAgSHAoUYnVsbHNleWVfZGlzdGFuY2VfZG0YDiABKA0SHAoUYnVsbHNleWVfYmVhcmluZ19yZWYYDyABKA0SFgoOYnVsbHNleWVfZmxhZ3MYECABKA0SGAoQYnVsbHNleWVfdWlkX3JlZhgRIAEoCSLiAQoES2luZBIUChBLaW5kX1Vuc3BlY2lmaWVkEAASDwoLS2luZF9DaXJjbGUQARISCg5LaW5kX1JlY3RhbmdsZRACEhEKDUtpbmRfRnJlZWZvcm0QAxIVChFLaW5kX1RlbGVzdHJhdGlvbhAEEhAKDEtpbmRfUG9seWdvbhAFEhYKEktpbmRfUmFuZ2luZ0NpcmNsZRAGEhEKDUtpbmRfQnVsbHNleWUQBxIQCgxLaW5kX0VsbGlwc2UQCBISCg5LaW5kX1ZlaGljbGUyRBAJEhIKDktpbmRfVmVoaWNsZTNEEAoidQoJU3R5bGVNb2RlEhkKFVN0eWxlTW9kZV9VbnNwZWNpZmllZBAAEhgKFFN0eWxlTW9kZV9TdHJva2VPbmx5EAESFgoSU3R5bGVNb2RlX0ZpbGxPbmx5EAISGwoXU3R5bGVNb2RlX1N0cm9rZUFuZEZpbGwQA0oECAwQDSLlAwoGTWFya2VyEiUKBGtpbmQYASABKA4yFy5tZXNodGFzdGljLk1hcmtlci5LaW5kEh8KBWNvbG9yGAIgASgOMhAubWVzaHRhc3RpYy5UZWFtEhIKCmNvbG9yX2FyZ2IYAyABKAcSEQoJcmVhZGluZXNzGAQgASgIEhIKCnBhcmVudF91aWQYBSABKAkSEwoLcGFyZW50X3R5cGUYBiABKAkSFwoPcGFyZW50X2NhbGxzaWduGAcgASgJEg8KB2ljb25zZXQYCCABKAkimAIKBEtpbmQSFAoQS2luZF9VbnNwZWNpZmllZBAAEg0KCUtpbmRfU3BvdBABEhEKDUtpbmRfV2F5cG9pbnQQAhITCg9LaW5kX0NoZWNrcG9pbnQQAxIVChFLaW5kX1NlbGZQb3NpdGlvbhAEEhMKD0tpbmRfU3ltYm9sMjUyNRAFEhAKDEtpbmRfU3BvdE1hcBAGEhMKD0tpbmRfQ3VzdG9tSWNvbhAHEhIKDktpbmRfR29Ub1BvaW50EAgSFQoRS2luZF9Jbml0aWFsUG9pbnQQCRIVChFLaW5kX0NvbnRhY3RQb2ludBAKEhgKFEtpbmRfT2JzZXJ2YXRpb25Qb3N0EAsSFAoQS2luZF9JbWFnZU1hcmtlchAMIs4BCg9SYW5nZUFuZEJlYXJpbmcSJwoGYW5jaG9yGAEgASgLMhcubWVzaHRhc3RpYy5Db3RHZW9Qb2ludBISCgphbmNob3JfdWlkGAIgASgJEhAKCHJhbmdlX2NtGAMgASgNEhQKDGJlYXJpbmdfY2RlZxgEIAEoDRImCgxzdHJva2VfY29sb3IYBSABKA4yEC5tZXNodGFzdGljLlRlYW0SEwoLc3Ryb2tlX2FyZ2IYBiABKAcSGQoRc3Ryb2tlX3dlaWdodF94MTAYByABKA0ihAQKBVJvdXRlEigKBm1ldGhvZBgBIAEoDjIYLm1lc2h0YXN0aWMuUm91dGUuTWV0aG9kEi4KCWRpcmVjdGlvbhgCIAEoDjIbLm1lc2h0YXN0aWMuUm91dGUuRGlyZWN0aW9uEg4KBnByZWZpeBgDIAEoCRIZChFzdHJva2Vfd2VpZ2h0X3gxMBgEIAEoDRIlCgVsaW5rcxgFIAMoCzIWLm1lc2h0YXN0aWMuUm91dGUuTGluaxIRCgl0cnVuY2F0ZWQYBiABKAgaYAoETGluaxImCgVwb2ludBgBIAEoCzIXLm1lc2h0YXN0aWMuQ290R2VvUG9pbnQSCwoDdWlkGAIgASgJEhAKCGNhbGxzaWduGAMgASgJEhEKCWxpbmtfdHlwZRgEIAEoDSKHAQoGTWV0aG9kEhYKEk1ldGhvZF9VbnNwZWNpZmllZBAAEhIKDk1ldGhvZF9Ecml2aW5nEAESEgoOTWV0aG9kX1dhbGtpbmcQAhIRCg1NZXRob2RfRmx5aW5nEAMSEwoPTWV0aG9kX1N3aW1taW5nEAQSFQoRTWV0aG9kX1dhdGVyY3JhZnQQBSJQCglEaXJlY3Rpb24SGQoVRGlyZWN0aW9uX1Vuc3BlY2lmaWVkEAASEwoPRGlyZWN0aW9uX0luZmlsEAESEwoPRGlyZWN0aW9uX0V4ZmlsEAIi1goKDUNhc2V2YWNSZXBvcnQSOAoKcHJlY2VkZW5jZRgBIAEoDjIkLm1lc2h0YXN0aWMuQ2FzZXZhY1JlcG9ydC5QcmVjZWRlbmNlEhcKD2VxdWlwbWVudF9mbGFncxgCIAEoDRIXCg9saXR0ZXJfcGF0aWVudHMYAyABKA0SGwoTYW1idWxhdG9yeV9wYXRpZW50cxgEIAEoDRI0CghzZWN1cml0eRgFIAEoDjIiLm1lc2h0YXN0aWMuQ2FzZXZhY1JlcG9ydC5TZWN1cml0eRI5CgtobHpfbWFya2luZxgGIAEoDjIkLm1lc2h0YXN0aWMuQ2FzZXZhY1JlcG9ydC5IbHpNYXJraW5nEhMKC3pvbmVfbWFya2VyGAcgASgJEhMKC3VzX21pbGl0YXJ5GAggASgNEhMKC3VzX2NpdmlsaWFuGAkgASgNEhcKD25vbl91c19taWxpdGFyeRgKIAEoDRIXCg9ub25fdXNfY2l2aWxpYW4YCyABKA0SCwoDZXB3GAwgASgNEg0KBWNoaWxkGA0gASgNEhUKDXRlcnJhaW5fZmxhZ3MYDiABKA0SEQoJZnJlcXVlbmN5GA8gASgJEg0KBXRpdGxlGBAgASgJEhcKD21lZGxpbmVfcmVtYXJrcxgRIAEoCRIUCgx1cmdlbnRfY291bnQYEiABKA0SHQoVdXJnZW50X3N1cmdpY2FsX2NvdW50GBMgASgNEhYKDnByaW9yaXR5X2NvdW50GBQgASgNEhUKDXJvdXRpbmVfY291bnQYFSABKA0SGQoRY29udmVuaWVuY2VfY291bnQYFiABKA0SGAoQZXF1aXBtZW50X2RldGFpbBgXIAEoCRIcChR6b25lX3Byb3RlY3RlZF9jb29yZBgYIAEoCRIZChF0ZXJyYWluX3Nsb3BlX2RpchgZIAEoCRIcChR0ZXJyYWluX290aGVyX2RldGFpbBgaIAEoCRIRCgltYXJrZWRfYnkYGyABKAkSEQoJb2JzdGFjbGVzGBwgASgJEhYKDndpbmRzX2FyZV9mcm9tGB0gASgJEhIKCmZyaWVuZGxpZXMYHiABKAkSDQoFZW5lbXkYHyABKAkSEwoLaGx6X3JlbWFya3MYICABKAkSJQoFem1pc3QYISADKAsyFi5tZXNodGFzdGljLlpNaXN0RW50cnkiqwEKClByZWNlZGVuY2USGgoWUHJlY2VkZW5jZV9VbnNwZWNpZmllZBAAEhUKEVByZWNlZGVuY2VfVXJnZW50EAESHQoZUHJlY2VkZW5jZV9VcmdlbnRTdXJnaWNhbBACEhcKE1ByZWNlZGVuY2VfUHJpb3JpdHkQAxIWChJQcmVjZWRlbmNlX1JvdXRpbmUQBBIaChZQcmVjZWRlbmNlX0NvbnZlbmllbmNlEAUimwEKCkhsek1hcmtpbmcSGgoWSGx6TWFya2luZ19VbnNwZWNpZmllZBAAEhUKEUhsek1hcmtpbmdfUGFuZWxzEAESGQoVSGx6TWFya2luZ19QeXJvU2lnbmFsEAISFAoQSGx6TWFya2luZ19TbW9rZRADEhMKD0hsek1hcmtpbmdfTm9uZRAEEhQKEEhsek1hcmtpbmdfT3RoZXIQBSKSAQoIU2VjdXJpdHkSGAoUU2VjdXJpdHlfVW5zcGVjaWZpZWQQABIUChBTZWN1cml0eV9Ob0VuZW15EAESGgoWU2VjdXJpdHlfUG9zc2libGVFbmVteRACEhgKFFNlY3VyaXR5X0VuZW15SW5BcmVhEAMSIAocU2VjdXJpdHlfRW5lbXlJbkFybWVkQ29udGFjdBAEIlIKClpNaXN0RW50cnkSDQoFdGl0bGUYASABKAkSCQoBehgCIAEoCRIJCgFtGAMgASgJEgkKAWkYBCABKAkSCQoBcxgFIAEoCRIJCgF0GAYgASgJIo0CCg5FbWVyZ2VuY3lBbGVydBItCgR0eXBlGAEgASgOMh8ubWVzaHRhc3RpYy5FbWVyZ2VuY3lBbGVydC5UeXBlEhUKDWF1dGhvcmluZ191aWQYAiABKAkSHAoUY2FuY2VsX3JlZmVyZW5jZV91aWQYAyABKAkilgEKBFR5cGUSFAoQVHlwZV9VbnNwZWNpZmllZBAAEhEKDVR5cGVfQWxlcnQ5MTEQARIUChBUeXBlX1JpbmdUaGVCZWxsEAISEgoOVHlwZV9JbkNvbnRhY3QQAxIZChVUeXBlX0dlb0ZlbmNlQnJlYWNoZWQQBBIPCgtUeXBlX0N1c3RvbRAFEg8KC1R5cGVfQ2FuY2VsEAYixgMKC1Rhc2tSZXF1ZXN0EhEKCXRhc2tfdHlwZRgBIAEoCRISCgp0YXJnZXRfdWlkGAIgASgJEhQKDGFzc2lnbmVlX3VpZBgDIAEoCRIyCghwcmlvcml0eRgEIAEoDjIgLm1lc2h0YXN0aWMuVGFza1JlcXVlc3QuUHJpb3JpdHkSLgoGc3RhdHVzGAUgASgOMh4ubWVzaHRhc3RpYy5UYXNrUmVxdWVzdC5TdGF0dXMSDAoEbm90ZRgGIAEoCSJ1CghQcmlvcml0eRIYChRQcmlvcml0eV9VbnNwZWNpZmllZBAAEhAKDFByaW9yaXR5X0xvdxABEhMKD1ByaW9yaXR5X05vcm1hbBACEhEKDVByaW9yaXR5X0hpZ2gQAxIVChFQcmlvcml0eV9Dcml0aWNhbBAEIpABCgZTdGF0dXMSFgoSU3RhdHVzX1Vuc3BlY2lmaWVkEAASEgoOU3RhdHVzX1BlbmRpbmcQARIXChNTdGF0dXNfQWNrbm93bGVkZ2VkEAISFQoRU3RhdHVzX0luUHJvZ3Jlc3MQAxIUChBTdGF0dXNfQ29tcGxldGVkEAQSFAoQU3RhdHVzX0NhbmNlbGxlZBAFImAKDlRBS0Vudmlyb25tZW50EhkKEXRlbXBlcmF0dXJlX2NfeDEwGAEgASgREhoKEndpbmRfZGlyZWN0aW9uX2RlZxgCIAEoDRIXCg93aW5kX3NwZWVkX2NtX3MYAyABKA0ijQMKCVNlbnNvckZvdhIuCgR0eXBlGAEgASgOMiAubWVzaHRhc3RpYy5TZW5zb3JGb3YuU2Vuc29yVHlwZRITCgthemltdXRoX2RlZxgCIAEoDRIUCgdyYW5nZV9tGAMgASgNSACIAQESGgoSZm92X2hvcml6b250YWxfZGVnGAQgASgNEhgKEGZvdl92ZXJ0aWNhbF9kZWcYBSABKA0SFQoNZWxldmF0aW9uX2RlZxgGIAEoERIQCghyb2xsX2RlZxgHIAEoERINCgVtb2RlbBgIIAEoCSKqAQoKU2Vuc29yVHlwZRIaChZTZW5zb3JUeXBlX1Vuc3BlY2lmaWVkEAASFQoRU2Vuc29yVHlwZV9DYW1lcmEQARIWChJTZW5zb3JUeXBlX1RoZXJtYWwQAhIUChBTZW5zb3JUeXBlX0xhc2VyEAMSEgoOU2Vuc29yVHlwZV9OdmcQBBIRCg1TZW5zb3JUeXBlX1JmEAUSFAoQU2Vuc29yVHlwZV9PdGhlchAGQgoKCF9yYW5nZV9tIlUKDlRha1RhbGtNZXNzYWdlEgwKBHRleHQYASABKAkSEwoLY2hhdHJvb21faWQYAiABKAkSDAoEbGFuZxgDIAEoCRISCgpmcm9tX3ZvaWNlGAQgASgIImgKD1Rha1RhbGtSb29tRGF0YRIbCg9zZW5kZXJfY2FsbHNpZ24YASABKAlCAhgBEg8KB3Jvb21faWQYAiABKAkSEQoJcm9vbV9uYW1lGAMgASgJEhQKDHBhcnRpY2lwYW50cxgEIAMoCSIeCgVNYXJ0aRIVCg1kZXN0X2NhbGxzaWduGAEgAygJIpkKCgtUQUtQYWNrZXRWMhIoCgtjb3RfdHlwZV9pZBgBIAEoDjITLm1lc2h0YXN0aWMuQ290VHlwZRIfCgNob3cYAiABKA4yEi5tZXNodGFzdGljLkNvdEhvdxIQCghjYWxsc2lnbhgDIAEoCRIeCgR0ZWFtGAQgASgOMhAubWVzaHRhc3RpYy5UZWFtEiQKBHJvbGUYBSABKA4yFi5tZXNodGFzdGljLk1lbWJlclJvbGUSEgoKbGF0aXR1ZGVfaRgGIAEoDxITCgtsb25naXR1ZGVfaRgHIAEoDxIQCghhbHRpdHVkZRgIIAEoERINCgVzcGVlZBgJIAEoDRIOCgZjb3Vyc2UYCiABKA0SDwoHYmF0dGVyeRgLIAEoDRIrCgdnZW9fc3JjGAwgASgOMhoubWVzaHRhc3RpYy5HZW9Qb2ludFNvdXJjZRIrCgdhbHRfc3JjGA0gASgOMhoubWVzaHRhc3RpYy5HZW9Qb2ludFNvdXJjZRILCgN1aWQYDiABKAkSFwoPZGV2aWNlX2NhbGxzaWduGA8gASgJEhUKDXN0YWxlX3NlY29uZHMYECABKA0SEwoLdGFrX3ZlcnNpb24YESABKAkSEgoKdGFrX2RldmljZRgSIAEoCRIUCgx0YWtfcGxhdGZvcm0YEyABKAkSDgoGdGFrX29zGBQgASgJEhAKCGVuZHBvaW50GBUgASgJEg0KBXBob25lGBYgASgJEhQKDGNvdF90eXBlX3N0chgXIAEoCRIPCgdyZW1hcmtzGBggASgJEjQKC2Vudmlyb25tZW50GBkgASgLMhoubWVzaHRhc3RpYy5UQUtFbnZpcm9ubWVudEgBiAEBEi4KCnNlbnNvcl9mb3YYGiABKAsyFS5tZXNodGFzdGljLlNlbnNvckZvdkgCiAEBEiUKBW1hcnRpGB0gASgLMhEubWVzaHRhc3RpYy5NYXJ0aUgDiAEBEiMKBGNoYXQYHyABKAsyEy5tZXNodGFzdGljLkdlb0NoYXRIABItCghhaXJjcmFmdBggIAEoCzIZLm1lc2h0YXN0aWMuQWlyY3JhZnRUcmFja0gAEhQKCnJhd19kZXRhaWwYISABKAxIABInCgVzaGFwZRgiIAEoCzIWLm1lc2h0YXN0aWMuRHJhd25TaGFwZUgAEiQKBm1hcmtlchgjIAEoCzISLm1lc2h0YXN0aWMuTWFya2VySAASKgoDcmFiGCQgASgLMhsubWVzaHRhc3RpYy5SYW5nZUFuZEJlYXJpbmdIABIiCgVyb3V0ZRglIAEoCzIRLm1lc2h0YXN0aWMuUm91dGVIABIsCgdjYXNldmFjGCYgASgLMhkubWVzaHRhc3RpYy5DYXNldmFjUmVwb3J0SAASLwoJZW1lcmdlbmN5GCcgASgLMhoubWVzaHRhc3RpYy5FbWVyZ2VuY3lBbGVydEgAEicKBHRhc2sYKCABKAsyFy5tZXNodGFzdGljLlRhc2tSZXF1ZXN0SAASLQoHdGFrdGFsaxgpIAEoCzIaLm1lc2h0YXN0aWMuVGFrVGFsa01lc3NhZ2VIABIzCgx0YWt0YWxrX3Jvb20YKiABKAsyGy5tZXNodGFzdGljLlRha1RhbGtSb29tRGF0YUgAQhEKD3BheWxvYWRfdmFyaWFudEIOCgxfZW52aXJvbm1lbnRCDQoLX3NlbnNvcl9mb3ZCCAoGX21hcnRpSgQIGxAcSgQIHBAdSgQIHhAfKsABCgRUZWFtEhQKEFVuc3BlY2lmZWRfQ29sb3IQABIJCgVXaGl0ZRABEgoKBlllbGxvdxACEgoKBk9yYW5nZRADEgsKB01hZ2VudGEQBBIHCgNSZWQQBRIKCgZNYXJvb24QBhIKCgZQdXJwbGUQBxINCglEYXJrX0JsdWUQCBIICgRCbHVlEAkSCAoEQ3lhbhAKEggKBFRlYWwQCxIJCgVHcmVlbhAMEg4KCkRhcmtfR3JlZW4QDRIJCgVCcm93bhAOKn8KCk1lbWJlclJvbGUSDgoKVW5zcGVjaWZlZBAAEg4KClRlYW1NZW1iZXIQARIMCghUZWFtTGVhZBACEgYKAkhREAMSCgoGU25pcGVyEAQSCQoFTWVkaWMQBRITCg9Gb3J3YXJkT2JzZXJ2ZXIQBhIHCgNSVE8QBxIGCgJLORAIKpYBCgZDb3RIb3cSFgoSQ290SG93X1Vuc3BlY2lmaWVkEAASDgoKQ290SG93X2hfZRABEg4KCkNvdEhvd19tX2cQAhIUChBDb3RIb3dfaF9nX2lfZ19vEAMSDgoKQ290SG93X21fchAEEg4KCkNvdEhvd19tX2YQBRIOCgpDb3RIb3dfbV9wEAYSDgoKQ290SG93X21fcxAHKoMXCgdDb3RUeXBlEhEKDUNvdFR5cGVfT3RoZXIQABIVChFDb3RUeXBlX2FfZl9HX1VfQxABEhcKE0NvdFR5cGVfYV9mX0dfVV9DX0kQAhIVChFDb3RUeXBlX2Ffbl9BX0NfRhADEhUKEUNvdFR5cGVfYV9uX0FfQ19IEAQSEwoPQ290VHlwZV9hX25fQV9DEAUSFQoRQ290VHlwZV9hX2ZfQV9NX0gQBhITCg9Db3RUeXBlX2FfZl9BX00QBxIXChNDb3RUeXBlX2FfZl9BX01fRl9GEAgSFwoTQ290VHlwZV9hX2ZfQV9NX0hfQRAJEhkKFUNvdFR5cGVfYV9mX0FfTV9IX1VfTRAKEhcKE0NvdFR5cGVfYV9oX0FfTV9GX0YQCxIXChNDb3RUeXBlX2FfaF9BX01fSF9BEAwSEwoPQ290VHlwZV9hX3VfQV9DEA0SEwoPQ290VHlwZV90X3hfZF9kEA4SFwoTQ290VHlwZV9hX2ZfR19FX1NfRRAPEhcKE0NvdFR5cGVfYV9mX0dfRV9WX0MQEBIRCg1Db3RUeXBlX2FfZl9TEBESFQoRQ290VHlwZV9hX2ZfQV9NX0YQEhIZChVDb3RUeXBlX2FfZl9BX01fRl9DX0gQExIZChVDb3RUeXBlX2FfZl9BX01fRl9VX0wQFBIXChNDb3RUeXBlX2FfZl9BX01fRl9MEBUSFwoTQ290VHlwZV9hX2ZfQV9NX0ZfUBAWEhUKEUNvdFR5cGVfYV9mX0FfQ19IEBcSFwoTQ290VHlwZV9hX25fQV9NX0ZfURAYEhEKDUNvdFR5cGVfYl90X2YQGRIVChFDb3RUeXBlX2Jfcl9mX2hfYxAaEhUKEUNvdFR5cGVfYl9hX29fcGFuEBsSFQoRQ290VHlwZV9iX2Ffb19vcG4QHBIVChFDb3RUeXBlX2JfYV9vX2NhbhAdEhUKEUNvdFR5cGVfYl9hX29fdGJsEB4SEQoNQ290VHlwZV9iX2FfZxAfEhEKDUNvdFR5cGVfYV9mX0cQIBITCg9Db3RUeXBlX2FfZl9HX1UQIRIRCg1Db3RUeXBlX2FfaF9HECISEQoNQ290VHlwZV9hX3VfRxAjEhEKDUNvdFR5cGVfYV9uX0cQJBIRCg1Db3RUeXBlX2JfbV9yECUSEwoPQ290VHlwZV9iX21fcF93ECYSFwoTQ290VHlwZV9iX21fcF9zX3BfaRAnEhEKDUNvdFR5cGVfdV9kX2YQKBIRCg1Db3RUeXBlX3VfZF9yECkSEwoPQ290VHlwZV91X2RfY19jECoSEgoOQ290VHlwZV91X3JiX2EQKxIRCg1Db3RUeXBlX2FfaF9BECwSEQoNQ290VHlwZV9hX3VfQRAtEhcKE0NvdFR5cGVfYV9mX0FfTV9IX1EQLhIVChFDb3RUeXBlX2FfZl9BX0NfRhAvEhMKD0NvdFR5cGVfYV9mX0FfQxAwEhUKEUNvdFR5cGVfYV9mX0FfQ19MEDESEQoNQ290VHlwZV9hX2ZfQRAyEhcKE0NvdFR5cGVfYV9mX0FfTV9IX0MQMxIXChNDb3RUeXBlX2Ffbl9BX01fRl9GEDQSFQoRQ290VHlwZV9hX3VfQV9DX0YQNRIbChdDb3RUeXBlX2FfZl9HX1VfQ19GX1RfQRA2EhkKFUNvdFR5cGVfYV9mX0dfVV9DX1ZfUxA3EhkKFUNvdFR5cGVfYV9mX0dfVV9DX1JfWBA4EhkKFUNvdFR5cGVfYV9mX0dfVV9DX0lfWhA5EhsKF0NvdFR5cGVfYV9mX0dfVV9DX0VfQ19XEDoSGQoVQ290VHlwZV9hX2ZfR19VX0NfSV9MEDsSGQoVQ290VHlwZV9hX2ZfR19VX0NfUl9PEDwSGQoVQ290VHlwZV9hX2ZfR19VX0NfUl9WED0SFQoRQ290VHlwZV9hX2ZfR19VX0gQPhIbChdDb3RUeXBlX2FfZl9HX1VfVV9NX1NfRRA/EhkKFUNvdFR5cGVfYV9mX0dfVV9TX01fQxBAEhUKEUNvdFR5cGVfYV9mX0dfRV9TEEESEwoPQ290VHlwZV9hX2ZfR19FEEISGQoVQ290VHlwZV9hX2ZfR19FX1ZfQ19VEEMSGgoWQ290VHlwZV9hX2ZfR19FX1ZfQ19wcxBEEhUKEUNvdFR5cGVfYV91X0dfRV9WEEUSFwoTQ290VHlwZV9hX2ZfU19OX05fUhBGEhMKD0NvdFR5cGVfYV9mX0ZfQhBHEhkKFUNvdFR5cGVfYl9tX3Bfc19wX2xvYxBIEhEKDUNvdFR5cGVfYl9pX3YQSRITCg9Db3RUeXBlX2JfZl90X3IQShITCg9Db3RUeXBlX2JfZl90X2EQSxITCg9Db3RUeXBlX3VfZF9mX20QTBIRCg1Db3RUeXBlX3VfZF9wEE0SFQoRQ290VHlwZV9iX21fcF9zX20QThITCg9Db3RUeXBlX2JfbV9wX2MQTxIVChFDb3RUeXBlX3Vfcl9iX2NfYxBQEhoKFkNvdFR5cGVfdV9yX2JfYnVsbHNleWUQURIXChNDb3RUeXBlX2FfZl9HX0VfVl9BEFISEQoNQ290VHlwZV9hX25fQRBTEhcKE0NvdFR5cGVfYV91X0dfVV9DX0YQVBIXChNDb3RUeXBlX2Ffbl9HX1VfQ19GEFUSFwoTQ290VHlwZV9hX2hfR19VX0NfRhBWEhcKE0NvdFR5cGVfYV9mX0dfVV9DX0YQVxITCg9Db3RUeXBlX2FfdV9HX0kQWBITCg9Db3RUeXBlX2Ffbl9HX0kQWRITCg9Db3RUeXBlX2FfaF9HX0kQWhITCg9Db3RUeXBlX2FfZl9HX0kQWxIXChNDb3RUeXBlX2FfdV9HX0VfWF9NEFwSFwoTQ290VHlwZV9hX25fR19FX1hfTRBdEhcKE0NvdFR5cGVfYV9oX0dfRV9YX00QXhIXChNDb3RUeXBlX2FfZl9HX0VfWF9NEF8SEQoNQ290VHlwZV9hX3VfUxBgEhEKDUNvdFR5cGVfYV9uX1MQYRIRCg1Db3RUeXBlX2FfaF9TEGISGQoVQ290VHlwZV9hX3VfR19VX0NfSV9kEGMSGQoVQ290VHlwZV9hX25fR19VX0NfSV9kEGQSGQoVQ290VHlwZV9hX2hfR19VX0NfSV9kEGUSGQoVQ290VHlwZV9hX2ZfR19VX0NfSV9kEGYSGQoVQ290VHlwZV9hX3VfR19FX1ZfQV9UEGcSGQoVQ290VHlwZV9hX25fR19FX1ZfQV9UEGgSGQoVQ290VHlwZV9hX2hfR19FX1ZfQV9UEGkSGQoVQ290VHlwZV9hX2ZfR19FX1ZfQV9UEGoSFwoTQ290VHlwZV9hX3VfR19VX0NfSRBrEhcKE0NvdFR5cGVfYV9uX0dfVV9DX0kQbBIXChNDb3RUeXBlX2FfaF9HX1VfQ19JEG0SFQoRQ290VHlwZV9hX25fR19FX1YQbhIVChFDb3RUeXBlX2FfaF9HX0VfVhBvEhUKEUNvdFR5cGVfYV9mX0dfRV9WEHASGAoUQ290VHlwZV9iX21fcF93X0dPVE8QcRIWChJDb3RUeXBlX2JfbV9wX2NfaXAQchIWChJDb3RUeXBlX2JfbV9wX2NfY3AQcxIYChRDb3RUeXBlX2JfbV9wX3NfcF9vcBB0EhEKDUNvdFR5cGVfdV9kX3YQdRITCg9Db3RUeXBlX3VfZF92X20QdhITCg9Db3RUeXBlX3VfZF9jX2UQdxITCg9Db3RUeXBlX2JfaV94X2kQeBITCg9Db3RUeXBlX2JfdF9mX2QQeRITCg9Db3RUeXBlX2JfdF9mX3IQehITCg9Db3RUeXBlX2JfYV9vX2MQexIPCgtDb3RUeXBlX3RfcxB8EhEKDUNvdFR5cGVfbV90X3QQfRINCglDb3RUeXBlX3kQfip9Cg5HZW9Qb2ludFNvdXJjZRIeChpHZW9Qb2ludFNvdXJjZV9VbnNwZWNpZmllZBAAEhYKEkdlb1BvaW50U291cmNlX0dQUxABEhcKE0dlb1BvaW50U291cmNlX1VTRVIQAhIaChZHZW9Qb2ludFNvdXJjZV9ORVRXT1JLEANCYAoUb3JnLm1lc2h0YXN0aWMucHJvdG9CCkFUQUtQcm90b3NaImdpdGh1Yi5jb20vbWVzaHRhc3RpYy9nby9nZW5lcmF0ZWSqAhRNZXNodGFzdGljLlByb3RvYnVmc7oCAGIGcHJvdG8z");
+export const file_meshtastic_atak: GenFile /*@__PURE__*/ = fileDesc(
+ "ChVtZXNodGFzdGljL2F0YWsucHJvdG8SCm1lc2h0YXN0aWMi+AEKCVRBS1BhY2tldBIVCg1pc19jb21wcmVzc2VkGAEgASgIEiQKB2NvbnRhY3QYAiABKAsyEy5tZXNodGFzdGljLkNvbnRhY3QSIAoFZ3JvdXAYAyABKAsyES5tZXNodGFzdGljLkdyb3VwEiIKBnN0YXR1cxgEIAEoCzISLm1lc2h0YXN0aWMuU3RhdHVzEh4KA3BsaRgFIAEoCzIPLm1lc2h0YXN0aWMuUExJSAASIwoEY2hhdBgGIAEoCzITLm1lc2h0YXN0aWMuR2VvQ2hhdEgAEhAKBmRldGFpbBgHIAEoDEgAQhEKD3BheWxvYWRfdmFyaWFudCL0AgoHR2VvQ2hhdBIPCgdtZXNzYWdlGAEgASgJEg8KAnRvGAIgASgJSACIAQESGAoLdG9fY2FsbHNpZ24YAyABKAlIAYgBARIXCg9yZWNlaXB0X2Zvcl91aWQYBCABKAkSNQoMcmVjZWlwdF90eXBlGAUgASgOMh8ubWVzaHRhc3RpYy5HZW9DaGF0LlJlY2VpcHRUeXBlEhEKBGxhbmcYBiABKAlIAogBARIUCgdyb29tX2lkGAcgASgJSAOIAQESHQoQdm9pY2VfcHJvZmlsZV9pZBgIIAEoCUgEiAEBIlQKC1JlY2VpcHRUeXBlEhQKEFJlY2VpcHRUeXBlX05vbmUQABIZChVSZWNlaXB0VHlwZV9EZWxpdmVyZWQQARIUChBSZWNlaXB0VHlwZV9SZWFkEAJCBQoDX3RvQg4KDF90b19jYWxsc2lnbkIHCgVfbGFuZ0IKCghfcm9vbV9pZEITChFfdm9pY2VfcHJvZmlsZV9pZCJNCgVHcm91cBIkCgRyb2xlGAEgASgOMhYubWVzaHRhc3RpYy5NZW1iZXJSb2xlEh4KBHRlYW0YAiABKA4yEC5tZXNodGFzdGljLlRlYW0iGQoGU3RhdHVzEg8KB2JhdHRlcnkYASABKA0iNAoHQ29udGFjdBIQCghjYWxsc2lnbhgBIAEoCRIXCg9kZXZpY2VfY2FsbHNpZ24YAiABKAkiXwoDUExJEhIKCmxhdGl0dWRlX2kYASABKA8SEwoLbG9uZ2l0dWRlX2kYAiABKA8SEAoIYWx0aXR1ZGUYAyABKAUSDQoFc3BlZWQYBCABKA0SDgoGY291cnNlGAUgASgNIrABCg1BaXJjcmFmdFRyYWNrEgwKBGljYW8YASABKAkSFAoMcmVnaXN0cmF0aW9uGAIgASgJEg4KBmZsaWdodBgDIAEoCRIVCg1haXJjcmFmdF90eXBlGAQgASgJEg4KBnNxdWF3axgFIAEoDRIQCghjYXRlZ29yeRgGIAEoCRIQCghyc3NpX3gxMBgHIAEoERILCgNncHMYCCABKAgSEwoLY290X2hvc3RfaWQYCSABKAkiNwoLQ290R2VvUG9pbnQSEwoLbGF0X2RlbHRhX2kYASABKBESEwoLbG9uX2RlbHRhX2kYAiABKBEi3AYKCkRyYXduU2hhcGUSKQoEa2luZBgBIAEoDjIbLm1lc2h0YXN0aWMuRHJhd25TaGFwZS5LaW5kEi8KBXN0eWxlGAIgASgOMiAubWVzaHRhc3RpYy5EcmF3blNoYXBlLlN0eWxlTW9kZRIQCghtYWpvcl9jbRgDIAEoDRIQCghtaW5vcl9jbRgEIAEoDRIRCglhbmdsZV9kZWcYBSABKA0SJgoMc3Ryb2tlX2NvbG9yGAYgASgOMhAubWVzaHRhc3RpYy5UZWFtEhMKC3N0cm9rZV9hcmdiGAcgASgHEhkKEXN0cm9rZV93ZWlnaHRfeDEwGAggASgNEiQKCmZpbGxfY29sb3IYCSABKA4yEC5tZXNodGFzdGljLlRlYW0SEQoJZmlsbF9hcmdiGAogASgHEhEKCWxhYmVsc19vbhgLIAEoCBIZChF2ZXJ0ZXhfbGF0X2RlbHRhcxgSIAMoERIZChF2ZXJ0ZXhfbG9uX2RlbHRhcxgTIAMoERIRCgl0cnVuY2F0ZWQYDSABKAgSHAoUYnVsbHNleWVfZGlzdGFuY2VfZG0YDiABKA0SHAoUYnVsbHNleWVfYmVhcmluZ19yZWYYDyABKA0SFgoOYnVsbHNleWVfZmxhZ3MYECABKA0SGAoQYnVsbHNleWVfdWlkX3JlZhgRIAEoCSLiAQoES2luZBIUChBLaW5kX1Vuc3BlY2lmaWVkEAASDwoLS2luZF9DaXJjbGUQARISCg5LaW5kX1JlY3RhbmdsZRACEhEKDUtpbmRfRnJlZWZvcm0QAxIVChFLaW5kX1RlbGVzdHJhdGlvbhAEEhAKDEtpbmRfUG9seWdvbhAFEhYKEktpbmRfUmFuZ2luZ0NpcmNsZRAGEhEKDUtpbmRfQnVsbHNleWUQBxIQCgxLaW5kX0VsbGlwc2UQCBISCg5LaW5kX1ZlaGljbGUyRBAJEhIKDktpbmRfVmVoaWNsZTNEEAoidQoJU3R5bGVNb2RlEhkKFVN0eWxlTW9kZV9VbnNwZWNpZmllZBAAEhgKFFN0eWxlTW9kZV9TdHJva2VPbmx5EAESFgoSU3R5bGVNb2RlX0ZpbGxPbmx5EAISGwoXU3R5bGVNb2RlX1N0cm9rZUFuZEZpbGwQA0oECAwQDSLlAwoGTWFya2VyEiUKBGtpbmQYASABKA4yFy5tZXNodGFzdGljLk1hcmtlci5LaW5kEh8KBWNvbG9yGAIgASgOMhAubWVzaHRhc3RpYy5UZWFtEhIKCmNvbG9yX2FyZ2IYAyABKAcSEQoJcmVhZGluZXNzGAQgASgIEhIKCnBhcmVudF91aWQYBSABKAkSEwoLcGFyZW50X3R5cGUYBiABKAkSFwoPcGFyZW50X2NhbGxzaWduGAcgASgJEg8KB2ljb25zZXQYCCABKAkimAIKBEtpbmQSFAoQS2luZF9VbnNwZWNpZmllZBAAEg0KCUtpbmRfU3BvdBABEhEKDUtpbmRfV2F5cG9pbnQQAhITCg9LaW5kX0NoZWNrcG9pbnQQAxIVChFLaW5kX1NlbGZQb3NpdGlvbhAEEhMKD0tpbmRfU3ltYm9sMjUyNRAFEhAKDEtpbmRfU3BvdE1hcBAGEhMKD0tpbmRfQ3VzdG9tSWNvbhAHEhIKDktpbmRfR29Ub1BvaW50EAgSFQoRS2luZF9Jbml0aWFsUG9pbnQQCRIVChFLaW5kX0NvbnRhY3RQb2ludBAKEhgKFEtpbmRfT2JzZXJ2YXRpb25Qb3N0EAsSFAoQS2luZF9JbWFnZU1hcmtlchAMIs4BCg9SYW5nZUFuZEJlYXJpbmcSJwoGYW5jaG9yGAEgASgLMhcubWVzaHRhc3RpYy5Db3RHZW9Qb2ludBISCgphbmNob3JfdWlkGAIgASgJEhAKCHJhbmdlX2NtGAMgASgNEhQKDGJlYXJpbmdfY2RlZxgEIAEoDRImCgxzdHJva2VfY29sb3IYBSABKA4yEC5tZXNodGFzdGljLlRlYW0SEwoLc3Ryb2tlX2FyZ2IYBiABKAcSGQoRc3Ryb2tlX3dlaWdodF94MTAYByABKA0ihAQKBVJvdXRlEigKBm1ldGhvZBgBIAEoDjIYLm1lc2h0YXN0aWMuUm91dGUuTWV0aG9kEi4KCWRpcmVjdGlvbhgCIAEoDjIbLm1lc2h0YXN0aWMuUm91dGUuRGlyZWN0aW9uEg4KBnByZWZpeBgDIAEoCRIZChFzdHJva2Vfd2VpZ2h0X3gxMBgEIAEoDRIlCgVsaW5rcxgFIAMoCzIWLm1lc2h0YXN0aWMuUm91dGUuTGluaxIRCgl0cnVuY2F0ZWQYBiABKAgaYAoETGluaxImCgVwb2ludBgBIAEoCzIXLm1lc2h0YXN0aWMuQ290R2VvUG9pbnQSCwoDdWlkGAIgASgJEhAKCGNhbGxzaWduGAMgASgJEhEKCWxpbmtfdHlwZRgEIAEoDSKHAQoGTWV0aG9kEhYKEk1ldGhvZF9VbnNwZWNpZmllZBAAEhIKDk1ldGhvZF9Ecml2aW5nEAESEgoOTWV0aG9kX1dhbGtpbmcQAhIRCg1NZXRob2RfRmx5aW5nEAMSEwoPTWV0aG9kX1N3aW1taW5nEAQSFQoRTWV0aG9kX1dhdGVyY3JhZnQQBSJQCglEaXJlY3Rpb24SGQoVRGlyZWN0aW9uX1Vuc3BlY2lmaWVkEAASEwoPRGlyZWN0aW9uX0luZmlsEAESEwoPRGlyZWN0aW9uX0V4ZmlsEAIi1goKDUNhc2V2YWNSZXBvcnQSOAoKcHJlY2VkZW5jZRgBIAEoDjIkLm1lc2h0YXN0aWMuQ2FzZXZhY1JlcG9ydC5QcmVjZWRlbmNlEhcKD2VxdWlwbWVudF9mbGFncxgCIAEoDRIXCg9saXR0ZXJfcGF0aWVudHMYAyABKA0SGwoTYW1idWxhdG9yeV9wYXRpZW50cxgEIAEoDRI0CghzZWN1cml0eRgFIAEoDjIiLm1lc2h0YXN0aWMuQ2FzZXZhY1JlcG9ydC5TZWN1cml0eRI5CgtobHpfbWFya2luZxgGIAEoDjIkLm1lc2h0YXN0aWMuQ2FzZXZhY1JlcG9ydC5IbHpNYXJraW5nEhMKC3pvbmVfbWFya2VyGAcgASgJEhMKC3VzX21pbGl0YXJ5GAggASgNEhMKC3VzX2NpdmlsaWFuGAkgASgNEhcKD25vbl91c19taWxpdGFyeRgKIAEoDRIXCg9ub25fdXNfY2l2aWxpYW4YCyABKA0SCwoDZXB3GAwgASgNEg0KBWNoaWxkGA0gASgNEhUKDXRlcnJhaW5fZmxhZ3MYDiABKA0SEQoJZnJlcXVlbmN5GA8gASgJEg0KBXRpdGxlGBAgASgJEhcKD21lZGxpbmVfcmVtYXJrcxgRIAEoCRIUCgx1cmdlbnRfY291bnQYEiABKA0SHQoVdXJnZW50X3N1cmdpY2FsX2NvdW50GBMgASgNEhYKDnByaW9yaXR5X2NvdW50GBQgASgNEhUKDXJvdXRpbmVfY291bnQYFSABKA0SGQoRY29udmVuaWVuY2VfY291bnQYFiABKA0SGAoQZXF1aXBtZW50X2RldGFpbBgXIAEoCRIcChR6b25lX3Byb3RlY3RlZF9jb29yZBgYIAEoCRIZChF0ZXJyYWluX3Nsb3BlX2RpchgZIAEoCRIcChR0ZXJyYWluX290aGVyX2RldGFpbBgaIAEoCRIRCgltYXJrZWRfYnkYGyABKAkSEQoJb2JzdGFjbGVzGBwgASgJEhYKDndpbmRzX2FyZV9mcm9tGB0gASgJEhIKCmZyaWVuZGxpZXMYHiABKAkSDQoFZW5lbXkYHyABKAkSEwoLaGx6X3JlbWFya3MYICABKAkSJQoFem1pc3QYISADKAsyFi5tZXNodGFzdGljLlpNaXN0RW50cnkiqwEKClByZWNlZGVuY2USGgoWUHJlY2VkZW5jZV9VbnNwZWNpZmllZBAAEhUKEVByZWNlZGVuY2VfVXJnZW50EAESHQoZUHJlY2VkZW5jZV9VcmdlbnRTdXJnaWNhbBACEhcKE1ByZWNlZGVuY2VfUHJpb3JpdHkQAxIWChJQcmVjZWRlbmNlX1JvdXRpbmUQBBIaChZQcmVjZWRlbmNlX0NvbnZlbmllbmNlEAUimwEKCkhsek1hcmtpbmcSGgoWSGx6TWFya2luZ19VbnNwZWNpZmllZBAAEhUKEUhsek1hcmtpbmdfUGFuZWxzEAESGQoVSGx6TWFya2luZ19QeXJvU2lnbmFsEAISFAoQSGx6TWFya2luZ19TbW9rZRADEhMKD0hsek1hcmtpbmdfTm9uZRAEEhQKEEhsek1hcmtpbmdfT3RoZXIQBSKSAQoIU2VjdXJpdHkSGAoUU2VjdXJpdHlfVW5zcGVjaWZpZWQQABIUChBTZWN1cml0eV9Ob0VuZW15EAESGgoWU2VjdXJpdHlfUG9zc2libGVFbmVteRACEhgKFFNlY3VyaXR5X0VuZW15SW5BcmVhEAMSIAocU2VjdXJpdHlfRW5lbXlJbkFybWVkQ29udGFjdBAEIlIKClpNaXN0RW50cnkSDQoFdGl0bGUYASABKAkSCQoBehgCIAEoCRIJCgFtGAMgASgJEgkKAWkYBCABKAkSCQoBcxgFIAEoCRIJCgF0GAYgASgJIo0CCg5FbWVyZ2VuY3lBbGVydBItCgR0eXBlGAEgASgOMh8ubWVzaHRhc3RpYy5FbWVyZ2VuY3lBbGVydC5UeXBlEhUKDWF1dGhvcmluZ191aWQYAiABKAkSHAoUY2FuY2VsX3JlZmVyZW5jZV91aWQYAyABKAkilgEKBFR5cGUSFAoQVHlwZV9VbnNwZWNpZmllZBAAEhEKDVR5cGVfQWxlcnQ5MTEQARIUChBUeXBlX1JpbmdUaGVCZWxsEAISEgoOVHlwZV9JbkNvbnRhY3QQAxIZChVUeXBlX0dlb0ZlbmNlQnJlYWNoZWQQBBIPCgtUeXBlX0N1c3RvbRAFEg8KC1R5cGVfQ2FuY2VsEAYixgMKC1Rhc2tSZXF1ZXN0EhEKCXRhc2tfdHlwZRgBIAEoCRISCgp0YXJnZXRfdWlkGAIgASgJEhQKDGFzc2lnbmVlX3VpZBgDIAEoCRIyCghwcmlvcml0eRgEIAEoDjIgLm1lc2h0YXN0aWMuVGFza1JlcXVlc3QuUHJpb3JpdHkSLgoGc3RhdHVzGAUgASgOMh4ubWVzaHRhc3RpYy5UYXNrUmVxdWVzdC5TdGF0dXMSDAoEbm90ZRgGIAEoCSJ1CghQcmlvcml0eRIYChRQcmlvcml0eV9VbnNwZWNpZmllZBAAEhAKDFByaW9yaXR5X0xvdxABEhMKD1ByaW9yaXR5X05vcm1hbBACEhEKDVByaW9yaXR5X0hpZ2gQAxIVChFQcmlvcml0eV9Dcml0aWNhbBAEIpABCgZTdGF0dXMSFgoSU3RhdHVzX1Vuc3BlY2lmaWVkEAASEgoOU3RhdHVzX1BlbmRpbmcQARIXChNTdGF0dXNfQWNrbm93bGVkZ2VkEAISFQoRU3RhdHVzX0luUHJvZ3Jlc3MQAxIUChBTdGF0dXNfQ29tcGxldGVkEAQSFAoQU3RhdHVzX0NhbmNlbGxlZBAFImAKDlRBS0Vudmlyb25tZW50EhkKEXRlbXBlcmF0dXJlX2NfeDEwGAEgASgREhoKEndpbmRfZGlyZWN0aW9uX2RlZxgCIAEoDRIXCg93aW5kX3NwZWVkX2NtX3MYAyABKA0ijQMKCVNlbnNvckZvdhIuCgR0eXBlGAEgASgOMiAubWVzaHRhc3RpYy5TZW5zb3JGb3YuU2Vuc29yVHlwZRITCgthemltdXRoX2RlZxgCIAEoDRIUCgdyYW5nZV9tGAMgASgNSACIAQESGgoSZm92X2hvcml6b250YWxfZGVnGAQgASgNEhgKEGZvdl92ZXJ0aWNhbF9kZWcYBSABKA0SFQoNZWxldmF0aW9uX2RlZxgGIAEoERIQCghyb2xsX2RlZxgHIAEoERINCgVtb2RlbBgIIAEoCSKqAQoKU2Vuc29yVHlwZRIaChZTZW5zb3JUeXBlX1Vuc3BlY2lmaWVkEAASFQoRU2Vuc29yVHlwZV9DYW1lcmEQARIWChJTZW5zb3JUeXBlX1RoZXJtYWwQAhIUChBTZW5zb3JUeXBlX0xhc2VyEAMSEgoOU2Vuc29yVHlwZV9OdmcQBBIRCg1TZW5zb3JUeXBlX1JmEAUSFAoQU2Vuc29yVHlwZV9PdGhlchAGQgoKCF9yYW5nZV9tIlUKDlRha1RhbGtNZXNzYWdlEgwKBHRleHQYASABKAkSEwoLY2hhdHJvb21faWQYAiABKAkSDAoEbGFuZxgDIAEoCRISCgpmcm9tX3ZvaWNlGAQgASgIImgKD1Rha1RhbGtSb29tRGF0YRIbCg9zZW5kZXJfY2FsbHNpZ24YASABKAlCAhgBEg8KB3Jvb21faWQYAiABKAkSEQoJcm9vbV9uYW1lGAMgASgJEhQKDHBhcnRpY2lwYW50cxgEIAMoCSIeCgVNYXJ0aRIVCg1kZXN0X2NhbGxzaWduGAEgAygJIpkKCgtUQUtQYWNrZXRWMhIoCgtjb3RfdHlwZV9pZBgBIAEoDjITLm1lc2h0YXN0aWMuQ290VHlwZRIfCgNob3cYAiABKA4yEi5tZXNodGFzdGljLkNvdEhvdxIQCghjYWxsc2lnbhgDIAEoCRIeCgR0ZWFtGAQgASgOMhAubWVzaHRhc3RpYy5UZWFtEiQKBHJvbGUYBSABKA4yFi5tZXNodGFzdGljLk1lbWJlclJvbGUSEgoKbGF0aXR1ZGVfaRgGIAEoDxITCgtsb25naXR1ZGVfaRgHIAEoDxIQCghhbHRpdHVkZRgIIAEoERINCgVzcGVlZBgJIAEoDRIOCgZjb3Vyc2UYCiABKA0SDwoHYmF0dGVyeRgLIAEoDRIrCgdnZW9fc3JjGAwgASgOMhoubWVzaHRhc3RpYy5HZW9Qb2ludFNvdXJjZRIrCgdhbHRfc3JjGA0gASgOMhoubWVzaHRhc3RpYy5HZW9Qb2ludFNvdXJjZRILCgN1aWQYDiABKAkSFwoPZGV2aWNlX2NhbGxzaWduGA8gASgJEhUKDXN0YWxlX3NlY29uZHMYECABKA0SEwoLdGFrX3ZlcnNpb24YESABKAkSEgoKdGFrX2RldmljZRgSIAEoCRIUCgx0YWtfcGxhdGZvcm0YEyABKAkSDgoGdGFrX29zGBQgASgJEhAKCGVuZHBvaW50GBUgASgJEg0KBXBob25lGBYgASgJEhQKDGNvdF90eXBlX3N0chgXIAEoCRIPCgdyZW1hcmtzGBggASgJEjQKC2Vudmlyb25tZW50GBkgASgLMhoubWVzaHRhc3RpYy5UQUtFbnZpcm9ubWVudEgBiAEBEi4KCnNlbnNvcl9mb3YYGiABKAsyFS5tZXNodGFzdGljLlNlbnNvckZvdkgCiAEBEiUKBW1hcnRpGB0gASgLMhEubWVzaHRhc3RpYy5NYXJ0aUgDiAEBEiMKBGNoYXQYHyABKAsyEy5tZXNodGFzdGljLkdlb0NoYXRIABItCghhaXJjcmFmdBggIAEoCzIZLm1lc2h0YXN0aWMuQWlyY3JhZnRUcmFja0gAEhQKCnJhd19kZXRhaWwYISABKAxIABInCgVzaGFwZRgiIAEoCzIWLm1lc2h0YXN0aWMuRHJhd25TaGFwZUgAEiQKBm1hcmtlchgjIAEoCzISLm1lc2h0YXN0aWMuTWFya2VySAASKgoDcmFiGCQgASgLMhsubWVzaHRhc3RpYy5SYW5nZUFuZEJlYXJpbmdIABIiCgVyb3V0ZRglIAEoCzIRLm1lc2h0YXN0aWMuUm91dGVIABIsCgdjYXNldmFjGCYgASgLMhkubWVzaHRhc3RpYy5DYXNldmFjUmVwb3J0SAASLwoJZW1lcmdlbmN5GCcgASgLMhoubWVzaHRhc3RpYy5FbWVyZ2VuY3lBbGVydEgAEicKBHRhc2sYKCABKAsyFy5tZXNodGFzdGljLlRhc2tSZXF1ZXN0SAASLQoHdGFrdGFsaxgpIAEoCzIaLm1lc2h0YXN0aWMuVGFrVGFsa01lc3NhZ2VIABIzCgx0YWt0YWxrX3Jvb20YKiABKAsyGy5tZXNodGFzdGljLlRha1RhbGtSb29tRGF0YUgAQhEKD3BheWxvYWRfdmFyaWFudEIOCgxfZW52aXJvbm1lbnRCDQoLX3NlbnNvcl9mb3ZCCAoGX21hcnRpSgQIGxAcSgQIHBAdSgQIHhAfKsABCgRUZWFtEhQKEFVuc3BlY2lmZWRfQ29sb3IQABIJCgVXaGl0ZRABEgoKBlllbGxvdxACEgoKBk9yYW5nZRADEgsKB01hZ2VudGEQBBIHCgNSZWQQBRIKCgZNYXJvb24QBhIKCgZQdXJwbGUQBxINCglEYXJrX0JsdWUQCBIICgRCbHVlEAkSCAoEQ3lhbhAKEggKBFRlYWwQCxIJCgVHcmVlbhAMEg4KCkRhcmtfR3JlZW4QDRIJCgVCcm93bhAOKn8KCk1lbWJlclJvbGUSDgoKVW5zcGVjaWZlZBAAEg4KClRlYW1NZW1iZXIQARIMCghUZWFtTGVhZBACEgYKAkhREAMSCgoGU25pcGVyEAQSCQoFTWVkaWMQBRITCg9Gb3J3YXJkT2JzZXJ2ZXIQBhIHCgNSVE8QBxIGCgJLORAIKpYBCgZDb3RIb3cSFgoSQ290SG93X1Vuc3BlY2lmaWVkEAASDgoKQ290SG93X2hfZRABEg4KCkNvdEhvd19tX2cQAhIUChBDb3RIb3dfaF9nX2lfZ19vEAMSDgoKQ290SG93X21fchAEEg4KCkNvdEhvd19tX2YQBRIOCgpDb3RIb3dfbV9wEAYSDgoKQ290SG93X21fcxAHKoMXCgdDb3RUeXBlEhEKDUNvdFR5cGVfT3RoZXIQABIVChFDb3RUeXBlX2FfZl9HX1VfQxABEhcKE0NvdFR5cGVfYV9mX0dfVV9DX0kQAhIVChFDb3RUeXBlX2Ffbl9BX0NfRhADEhUKEUNvdFR5cGVfYV9uX0FfQ19IEAQSEwoPQ290VHlwZV9hX25fQV9DEAUSFQoRQ290VHlwZV9hX2ZfQV9NX0gQBhITCg9Db3RUeXBlX2FfZl9BX00QBxIXChNDb3RUeXBlX2FfZl9BX01fRl9GEAgSFwoTQ290VHlwZV9hX2ZfQV9NX0hfQRAJEhkKFUNvdFR5cGVfYV9mX0FfTV9IX1VfTRAKEhcKE0NvdFR5cGVfYV9oX0FfTV9GX0YQCxIXChNDb3RUeXBlX2FfaF9BX01fSF9BEAwSEwoPQ290VHlwZV9hX3VfQV9DEA0SEwoPQ290VHlwZV90X3hfZF9kEA4SFwoTQ290VHlwZV9hX2ZfR19FX1NfRRAPEhcKE0NvdFR5cGVfYV9mX0dfRV9WX0MQEBIRCg1Db3RUeXBlX2FfZl9TEBESFQoRQ290VHlwZV9hX2ZfQV9NX0YQEhIZChVDb3RUeXBlX2FfZl9BX01fRl9DX0gQExIZChVDb3RUeXBlX2FfZl9BX01fRl9VX0wQFBIXChNDb3RUeXBlX2FfZl9BX01fRl9MEBUSFwoTQ290VHlwZV9hX2ZfQV9NX0ZfUBAWEhUKEUNvdFR5cGVfYV9mX0FfQ19IEBcSFwoTQ290VHlwZV9hX25fQV9NX0ZfURAYEhEKDUNvdFR5cGVfYl90X2YQGRIVChFDb3RUeXBlX2Jfcl9mX2hfYxAaEhUKEUNvdFR5cGVfYl9hX29fcGFuEBsSFQoRQ290VHlwZV9iX2Ffb19vcG4QHBIVChFDb3RUeXBlX2JfYV9vX2NhbhAdEhUKEUNvdFR5cGVfYl9hX29fdGJsEB4SEQoNQ290VHlwZV9iX2FfZxAfEhEKDUNvdFR5cGVfYV9mX0cQIBITCg9Db3RUeXBlX2FfZl9HX1UQIRIRCg1Db3RUeXBlX2FfaF9HECISEQoNQ290VHlwZV9hX3VfRxAjEhEKDUNvdFR5cGVfYV9uX0cQJBIRCg1Db3RUeXBlX2JfbV9yECUSEwoPQ290VHlwZV9iX21fcF93ECYSFwoTQ290VHlwZV9iX21fcF9zX3BfaRAnEhEKDUNvdFR5cGVfdV9kX2YQKBIRCg1Db3RUeXBlX3VfZF9yECkSEwoPQ290VHlwZV91X2RfY19jECoSEgoOQ290VHlwZV91X3JiX2EQKxIRCg1Db3RUeXBlX2FfaF9BECwSEQoNQ290VHlwZV9hX3VfQRAtEhcKE0NvdFR5cGVfYV9mX0FfTV9IX1EQLhIVChFDb3RUeXBlX2FfZl9BX0NfRhAvEhMKD0NvdFR5cGVfYV9mX0FfQxAwEhUKEUNvdFR5cGVfYV9mX0FfQ19MEDESEQoNQ290VHlwZV9hX2ZfQRAyEhcKE0NvdFR5cGVfYV9mX0FfTV9IX0MQMxIXChNDb3RUeXBlX2Ffbl9BX01fRl9GEDQSFQoRQ290VHlwZV9hX3VfQV9DX0YQNRIbChdDb3RUeXBlX2FfZl9HX1VfQ19GX1RfQRA2EhkKFUNvdFR5cGVfYV9mX0dfVV9DX1ZfUxA3EhkKFUNvdFR5cGVfYV9mX0dfVV9DX1JfWBA4EhkKFUNvdFR5cGVfYV9mX0dfVV9DX0lfWhA5EhsKF0NvdFR5cGVfYV9mX0dfVV9DX0VfQ19XEDoSGQoVQ290VHlwZV9hX2ZfR19VX0NfSV9MEDsSGQoVQ290VHlwZV9hX2ZfR19VX0NfUl9PEDwSGQoVQ290VHlwZV9hX2ZfR19VX0NfUl9WED0SFQoRQ290VHlwZV9hX2ZfR19VX0gQPhIbChdDb3RUeXBlX2FfZl9HX1VfVV9NX1NfRRA/EhkKFUNvdFR5cGVfYV9mX0dfVV9TX01fQxBAEhUKEUNvdFR5cGVfYV9mX0dfRV9TEEESEwoPQ290VHlwZV9hX2ZfR19FEEISGQoVQ290VHlwZV9hX2ZfR19FX1ZfQ19VEEMSGgoWQ290VHlwZV9hX2ZfR19FX1ZfQ19wcxBEEhUKEUNvdFR5cGVfYV91X0dfRV9WEEUSFwoTQ290VHlwZV9hX2ZfU19OX05fUhBGEhMKD0NvdFR5cGVfYV9mX0ZfQhBHEhkKFUNvdFR5cGVfYl9tX3Bfc19wX2xvYxBIEhEKDUNvdFR5cGVfYl9pX3YQSRITCg9Db3RUeXBlX2JfZl90X3IQShITCg9Db3RUeXBlX2JfZl90X2EQSxITCg9Db3RUeXBlX3VfZF9mX20QTBIRCg1Db3RUeXBlX3VfZF9wEE0SFQoRQ290VHlwZV9iX21fcF9zX20QThITCg9Db3RUeXBlX2JfbV9wX2MQTxIVChFDb3RUeXBlX3Vfcl9iX2NfYxBQEhoKFkNvdFR5cGVfdV9yX2JfYnVsbHNleWUQURIXChNDb3RUeXBlX2FfZl9HX0VfVl9BEFISEQoNQ290VHlwZV9hX25fQRBTEhcKE0NvdFR5cGVfYV91X0dfVV9DX0YQVBIXChNDb3RUeXBlX2Ffbl9HX1VfQ19GEFUSFwoTQ290VHlwZV9hX2hfR19VX0NfRhBWEhcKE0NvdFR5cGVfYV9mX0dfVV9DX0YQVxITCg9Db3RUeXBlX2FfdV9HX0kQWBITCg9Db3RUeXBlX2Ffbl9HX0kQWRITCg9Db3RUeXBlX2FfaF9HX0kQWhITCg9Db3RUeXBlX2FfZl9HX0kQWxIXChNDb3RUeXBlX2FfdV9HX0VfWF9NEFwSFwoTQ290VHlwZV9hX25fR19FX1hfTRBdEhcKE0NvdFR5cGVfYV9oX0dfRV9YX00QXhIXChNDb3RUeXBlX2FfZl9HX0VfWF9NEF8SEQoNQ290VHlwZV9hX3VfUxBgEhEKDUNvdFR5cGVfYV9uX1MQYRIRCg1Db3RUeXBlX2FfaF9TEGISGQoVQ290VHlwZV9hX3VfR19VX0NfSV9kEGMSGQoVQ290VHlwZV9hX25fR19VX0NfSV9kEGQSGQoVQ290VHlwZV9hX2hfR19VX0NfSV9kEGUSGQoVQ290VHlwZV9hX2ZfR19VX0NfSV9kEGYSGQoVQ290VHlwZV9hX3VfR19FX1ZfQV9UEGcSGQoVQ290VHlwZV9hX25fR19FX1ZfQV9UEGgSGQoVQ290VHlwZV9hX2hfR19FX1ZfQV9UEGkSGQoVQ290VHlwZV9hX2ZfR19FX1ZfQV9UEGoSFwoTQ290VHlwZV9hX3VfR19VX0NfSRBrEhcKE0NvdFR5cGVfYV9uX0dfVV9DX0kQbBIXChNDb3RUeXBlX2FfaF9HX1VfQ19JEG0SFQoRQ290VHlwZV9hX25fR19FX1YQbhIVChFDb3RUeXBlX2FfaF9HX0VfVhBvEhUKEUNvdFR5cGVfYV9mX0dfRV9WEHASGAoUQ290VHlwZV9iX21fcF93X0dPVE8QcRIWChJDb3RUeXBlX2JfbV9wX2NfaXAQchIWChJDb3RUeXBlX2JfbV9wX2NfY3AQcxIYChRDb3RUeXBlX2JfbV9wX3NfcF9vcBB0EhEKDUNvdFR5cGVfdV9kX3YQdRITCg9Db3RUeXBlX3VfZF92X20QdhITCg9Db3RUeXBlX3VfZF9jX2UQdxITCg9Db3RUeXBlX2JfaV94X2kQeBITCg9Db3RUeXBlX2JfdF9mX2QQeRITCg9Db3RUeXBlX2JfdF9mX3IQehITCg9Db3RUeXBlX2JfYV9vX2MQexIPCgtDb3RUeXBlX3RfcxB8EhEKDUNvdFR5cGVfbV90X3QQfRINCglDb3RUeXBlX3kQfip9Cg5HZW9Qb2ludFNvdXJjZRIeChpHZW9Qb2ludFNvdXJjZV9VbnNwZWNpZmllZBAAEhYKEkdlb1BvaW50U291cmNlX0dQUxABEhcKE0dlb1BvaW50U291cmNlX1VTRVIQAhIaChZHZW9Qb2ludFNvdXJjZV9ORVRXT1JLEANCYAoUb3JnLm1lc2h0YXN0aWMucHJvdG9CCkFUQUtQcm90b3NaImdpdGh1Yi5jb20vbWVzaHRhc3RpYy9nby9nZW5lcmF0ZWSqAhRNZXNodGFzdGljLlByb3RvYnVmc7oCAGIGcHJvdG8z",
+);
/**
*
@@ -59,43 +64,49 @@ export type TAKPacket = Message<"meshtastic.TAKPacket"> & {
*
* @generated from oneof meshtastic.TAKPacket.payload_variant
*/
- payloadVariant: {
- /**
- *
- * TAK position report
- *
- * @generated from field: meshtastic.PLI pli = 5;
- */
- value: PLI;
- case: "pli";
- } | {
- /**
- *
- * ATAK GeoChat message
- *
- * @generated from field: meshtastic.GeoChat chat = 6;
- */
- value: GeoChat;
- case: "chat";
- } | {
- /**
- *
- * Generic CoT detail XML
- * May be compressed / truncated by the sender (EUD)
- *
- * @generated from field: bytes detail = 7;
- */
- value: Uint8Array;
- case: "detail";
- } | { case: undefined; value?: undefined };
+ payloadVariant:
+ | {
+ /**
+ *
+ * TAK position report
+ *
+ * @generated from field: meshtastic.PLI pli = 5;
+ */
+ value: PLI;
+ case: "pli";
+ }
+ | {
+ /**
+ *
+ * ATAK GeoChat message
+ *
+ * @generated from field: meshtastic.GeoChat chat = 6;
+ */
+ value: GeoChat;
+ case: "chat";
+ }
+ | {
+ /**
+ *
+ * Generic CoT detail XML
+ * May be compressed / truncated by the sender (EUD)
+ *
+ * @generated from field: bytes detail = 7;
+ */
+ value: Uint8Array;
+ case: "detail";
+ }
+ | { case: undefined; value?: undefined };
};
/**
* Describes the message meshtastic.TAKPacket.
* Use `create(TAKPacketSchema)` to create a new message.
*/
-export const TAKPacketSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_meshtastic_atak, 0);
+export const TAKPacketSchema: GenMessage /*@__PURE__*/ = messageDesc(
+ file_meshtastic_atak,
+ 0,
+);
/**
*
@@ -183,8 +194,10 @@ export type GeoChat = Message<"meshtastic.GeoChat"> & {
* Describes the message meshtastic.GeoChat.
* Use `create(GeoChatSchema)` to create a new message.
*/
-export const GeoChatSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_meshtastic_atak, 1);
+export const GeoChatSchema: GenMessage /*@__PURE__*/ = messageDesc(
+ file_meshtastic_atak,
+ 1,
+);
/**
*
@@ -223,7 +236,7 @@ export enum GeoChat_ReceiptType {
/**
* Describes the enum meshtastic.GeoChat.ReceiptType.
*/
-export const GeoChat_ReceiptTypeSchema: GenEnum = /*@__PURE__*/
+export const GeoChat_ReceiptTypeSchema: GenEnum /*@__PURE__*/ =
enumDesc(file_meshtastic_atak, 1, 0);
/**
@@ -256,8 +269,10 @@ export type Group = Message<"meshtastic.Group"> & {
* Describes the message meshtastic.Group.
* Use `create(GroupSchema)` to create a new message.
*/
-export const GroupSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_meshtastic_atak, 2);
+export const GroupSchema: GenMessage /*@__PURE__*/ = messageDesc(
+ file_meshtastic_atak,
+ 2,
+);
/**
*
@@ -280,8 +295,10 @@ export type Status = Message<"meshtastic.Status"> & {
* Describes the message meshtastic.Status.
* Use `create(StatusSchema)` to create a new message.
*/
-export const StatusSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_meshtastic_atak, 3);
+export const StatusSchema: GenMessage /*@__PURE__*/ = messageDesc(
+ file_meshtastic_atak,
+ 3,
+);
/**
*
@@ -315,8 +332,10 @@ export type Contact = Message<"meshtastic.Contact"> & {
* Describes the message meshtastic.Contact.
* Use `create(ContactSchema)` to create a new message.
*/
-export const ContactSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_meshtastic_atak, 4);
+export const ContactSchema: GenMessage /*@__PURE__*/ = messageDesc(
+ file_meshtastic_atak,
+ 4,
+);
/**
*
@@ -372,8 +391,10 @@ export type PLI = Message<"meshtastic.PLI"> & {
* Describes the message meshtastic.PLI.
* Use `create(PLISchema)` to create a new message.
*/
-export const PLISchema: GenMessage = /*@__PURE__*/
- messageDesc(file_meshtastic_atak, 5);
+export const PLISchema: GenMessage /*@__PURE__*/ = messageDesc(
+ file_meshtastic_atak,
+ 5,
+);
/**
*
@@ -460,7 +481,7 @@ export type AircraftTrack = Message<"meshtastic.AircraftTrack"> & {
* Describes the message meshtastic.AircraftTrack.
* Use `create(AircraftTrackSchema)` to create a new message.
*/
-export const AircraftTrackSchema: GenMessage = /*@__PURE__*/
+export const AircraftTrackSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_atak, 6);
/**
@@ -509,7 +530,7 @@ export type CotGeoPoint = Message<"meshtastic.CotGeoPoint"> & {
* Describes the message meshtastic.CotGeoPoint.
* Use `create(CotGeoPointSchema)` to create a new message.
*/
-export const CotGeoPointSchema: GenMessage = /*@__PURE__*/
+export const CotGeoPointSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_atak, 7);
/**
@@ -687,7 +708,7 @@ export type DrawnShape = Message<"meshtastic.DrawnShape"> & {
* Describes the message meshtastic.DrawnShape.
* Use `create(DrawnShapeSchema)` to create a new message.
*/
-export const DrawnShapeSchema: GenMessage = /*@__PURE__*/
+export const DrawnShapeSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_atak, 8);
/**
@@ -794,7 +815,7 @@ export enum DrawnShape_Kind {
/**
* Describes the enum meshtastic.DrawnShape.Kind.
*/
-export const DrawnShape_KindSchema: GenEnum = /*@__PURE__*/
+export const DrawnShape_KindSchema: GenEnum /*@__PURE__*/ =
enumDesc(file_meshtastic_atak, 8, 0);
/**
@@ -850,7 +871,7 @@ export enum DrawnShape_StyleMode {
/**
* Describes the enum meshtastic.DrawnShape.StyleMode.
*/
-export const DrawnShape_StyleModeSchema: GenEnum = /*@__PURE__*/
+export const DrawnShape_StyleModeSchema: GenEnum /*@__PURE__*/ =
enumDesc(file_meshtastic_atak, 8, 1);
/**
@@ -943,8 +964,10 @@ export type Marker = Message<"meshtastic.Marker"> & {
* Describes the message meshtastic.Marker.
* Use `create(MarkerSchema)` to create a new message.
*/
-export const MarkerSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_meshtastic_atak, 9);
+export const MarkerSchema: GenMessage /*@__PURE__*/ = messageDesc(
+ file_meshtastic_atak,
+ 9,
+);
/**
*
@@ -1065,8 +1088,11 @@ export enum Marker_Kind {
/**
* Describes the enum meshtastic.Marker.Kind.
*/
-export const Marker_KindSchema: GenEnum = /*@__PURE__*/
- enumDesc(file_meshtastic_atak, 9, 0);
+export const Marker_KindSchema: GenEnum /*@__PURE__*/ = enumDesc(
+ file_meshtastic_atak,
+ 9,
+ 0,
+);
/**
*
@@ -1141,7 +1167,7 @@ export type RangeAndBearing = Message<"meshtastic.RangeAndBearing"> & {
* Describes the message meshtastic.RangeAndBearing.
* Use `create(RangeAndBearingSchema)` to create a new message.
*/
-export const RangeAndBearingSchema: GenMessage = /*@__PURE__*/
+export const RangeAndBearingSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_atak, 10);
/**
@@ -1209,8 +1235,10 @@ export type Route = Message<"meshtastic.Route"> & {
* Describes the message meshtastic.Route.
* Use `create(RouteSchema)` to create a new message.
*/
-export const RouteSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_meshtastic_atak, 11);
+export const RouteSchema: GenMessage /*@__PURE__*/ = messageDesc(
+ file_meshtastic_atak,
+ 11,
+);
/**
*
@@ -1257,7 +1285,7 @@ export type Route_Link = Message<"meshtastic.Route.Link"> & {
* Describes the message meshtastic.Route.Link.
* Use `create(Route_LinkSchema)` to create a new message.
*/
-export const Route_LinkSchema: GenMessage = /*@__PURE__*/
+export const Route_LinkSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_atak, 11, 0);
/**
@@ -1319,8 +1347,11 @@ export enum Route_Method {
/**
* Describes the enum meshtastic.Route.Method.
*/
-export const Route_MethodSchema: GenEnum = /*@__PURE__*/
- enumDesc(file_meshtastic_atak, 11, 0);
+export const Route_MethodSchema: GenEnum /*@__PURE__*/ = enumDesc(
+ file_meshtastic_atak,
+ 11,
+ 0,
+);
/**
*
@@ -1357,7 +1388,7 @@ export enum Route_Direction {
/**
* Describes the enum meshtastic.Route.Direction.
*/
-export const Route_DirectionSchema: GenEnum = /*@__PURE__*/
+export const Route_DirectionSchema: GenEnum /*@__PURE__*/ =
enumDesc(file_meshtastic_atak, 11, 1);
/**
@@ -1654,7 +1685,7 @@ export type CasevacReport = Message<"meshtastic.CasevacReport"> & {
* Describes the message meshtastic.CasevacReport.
* Use `create(CasevacReportSchema)` to create a new message.
*/
-export const CasevacReportSchema: GenMessage = /*@__PURE__*/
+export const CasevacReportSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_atak, 12);
/**
@@ -1708,7 +1739,7 @@ export enum CasevacReport_Precedence {
/**
* Describes the enum meshtastic.CasevacReport.Precedence.
*/
-export const CasevacReport_PrecedenceSchema: GenEnum = /*@__PURE__*/
+export const CasevacReport_PrecedenceSchema: GenEnum /*@__PURE__*/ =
enumDesc(file_meshtastic_atak, 12, 0);
/**
@@ -1752,7 +1783,7 @@ export enum CasevacReport_HlzMarking {
/**
* Describes the enum meshtastic.CasevacReport.HlzMarking.
*/
-export const CasevacReport_HlzMarkingSchema: GenEnum = /*@__PURE__*/
+export const CasevacReport_HlzMarkingSchema: GenEnum /*@__PURE__*/ =
enumDesc(file_meshtastic_atak, 12, 1);
/**
@@ -1799,7 +1830,7 @@ export enum CasevacReport_Security {
/**
* Describes the enum meshtastic.CasevacReport.Security.
*/
-export const CasevacReport_SecuritySchema: GenEnum = /*@__PURE__*/
+export const CasevacReport_SecuritySchema: GenEnum /*@__PURE__*/ =
enumDesc(file_meshtastic_atak, 12, 2);
/**
@@ -1865,7 +1896,7 @@ export type ZMistEntry = Message<"meshtastic.ZMistEntry"> & {
* Describes the message meshtastic.ZMistEntry.
* Use `create(ZMistEntrySchema)` to create a new message.
*/
-export const ZMistEntrySchema: GenMessage = /*@__PURE__*/
+export const ZMistEntrySchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_atak, 13);
/**
@@ -1913,7 +1944,7 @@ export type EmergencyAlert = Message<"meshtastic.EmergencyAlert"> & {
* Describes the message meshtastic.EmergencyAlert.
* Use `create(EmergencyAlertSchema)` to create a new message.
*/
-export const EmergencyAlertSchema: GenMessage = /*@__PURE__*/
+export const EmergencyAlertSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_atak, 14);
/**
@@ -1971,7 +2002,7 @@ export enum EmergencyAlert_Type {
/**
* Describes the enum meshtastic.EmergencyAlert.Type.
*/
-export const EmergencyAlert_TypeSchema: GenEnum = /*@__PURE__*/
+export const EmergencyAlert_TypeSchema: GenEnum /*@__PURE__*/ =
enumDesc(file_meshtastic_atak, 14, 0);
/**
@@ -2039,7 +2070,7 @@ export type TaskRequest = Message<"meshtastic.TaskRequest"> & {
* Describes the message meshtastic.TaskRequest.
* Use `create(TaskRequestSchema)` to create a new message.
*/
-export const TaskRequestSchema: GenMessage = /*@__PURE__*/
+export const TaskRequestSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_atak, 15);
/**
@@ -2075,7 +2106,7 @@ export enum TaskRequest_Priority {
/**
* Describes the enum meshtastic.TaskRequest.Priority.
*/
-export const TaskRequest_PrioritySchema: GenEnum = /*@__PURE__*/
+export const TaskRequest_PrioritySchema: GenEnum /*@__PURE__*/ =
enumDesc(file_meshtastic_atak, 15, 0);
/**
@@ -2126,7 +2157,7 @@ export enum TaskRequest_Status {
/**
* Describes the enum meshtastic.TaskRequest.Status.
*/
-export const TaskRequest_StatusSchema: GenEnum = /*@__PURE__*/
+export const TaskRequest_StatusSchema: GenEnum /*@__PURE__*/ =
enumDesc(file_meshtastic_atak, 15, 1);
/**
@@ -2186,7 +2217,7 @@ export type TAKEnvironment = Message<"meshtastic.TAKEnvironment"> & {
* Describes the message meshtastic.TAKEnvironment.
* Use `create(TAKEnvironmentSchema)` to create a new message.
*/
-export const TAKEnvironmentSchema: GenMessage = /*@__PURE__*/
+export const TAKEnvironmentSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_atak, 16);
/**
@@ -2281,8 +2312,10 @@ export type SensorFov = Message<"meshtastic.SensorFov"> & {
* Describes the message meshtastic.SensorFov.
* Use `create(SensorFovSchema)` to create a new message.
*/
-export const SensorFovSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_meshtastic_atak, 17);
+export const SensorFovSchema: GenMessage /*@__PURE__*/ = messageDesc(
+ file_meshtastic_atak,
+ 17,
+);
/**
*
@@ -2342,7 +2375,7 @@ export enum SensorFov_SensorType {
/**
* Describes the enum meshtastic.SensorFov.SensorType.
*/
-export const SensorFov_SensorTypeSchema: GenEnum = /*@__PURE__*/
+export const SensorFov_SensorTypeSchema: GenEnum /*@__PURE__*/ =
enumDesc(file_meshtastic_atak, 17, 0);
/**
@@ -2409,7 +2442,7 @@ export type TakTalkMessage = Message<"meshtastic.TakTalkMessage"> & {
* Describes the message meshtastic.TakTalkMessage.
* Use `create(TakTalkMessageSchema)` to create a new message.
*/
-export const TakTalkMessageSchema: GenMessage = /*@__PURE__*/
+export const TakTalkMessageSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_atak, 18);
/**
@@ -2472,7 +2505,7 @@ export type TakTalkRoomData = Message<"meshtastic.TakTalkRoomData"> & {
* Describes the message meshtastic.TakTalkRoomData.
* Use `create(TakTalkRoomDataSchema)` to create a new message.
*/
-export const TakTalkRoomDataSchema: GenMessage = /*@__PURE__*/
+export const TakTalkRoomDataSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_atak, 19);
/**
@@ -2511,8 +2544,10 @@ export type Marti = Message<"meshtastic.Marti"> & {
* Describes the message meshtastic.Marti.
* Use `create(MartiSchema)` to create a new message.
*/
-export const MartiSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_meshtastic_atak, 20);
+export const MartiSchema: GenMessage /*@__PURE__*/ = messageDesc(
+ file_meshtastic_atak,
+ 20,
+);
/**
*
@@ -2774,130 +2809,143 @@ export type TAKPacketV2 = Message<"meshtastic.TAKPacketV2"> & {
*
* @generated from oneof meshtastic.TAKPacketV2.payload_variant
*/
- payloadVariant: {
- /**
- *
- * ATAK GeoChat message
- *
- * @generated from field: meshtastic.GeoChat chat = 31;
- */
- value: GeoChat;
- case: "chat";
- } | {
- /**
- *
- * Aircraft track data (ADS-B, military air)
- *
- * @generated from field: meshtastic.AircraftTrack aircraft = 32;
- */
- value: AircraftTrack;
- case: "aircraft";
- } | {
- /**
- *
- * Generic CoT detail XML for unmapped types. Kept as a fallback for CoT
- * types not yet promoted to a typed variant; drawings, markers, ranging
- * tools, and routes have dedicated variants below and should not land here.
- *
- * @generated from field: bytes raw_detail = 33;
- */
- value: Uint8Array;
- case: "rawDetail";
- } | {
- /**
- *
- * User-drawn tactical graphic: circle, rectangle, polygon, polyline,
- * telestration, ranging circle, or bullseye. See DrawnShape.
- *
- * @generated from field: meshtastic.DrawnShape shape = 34;
- */
- value: DrawnShape;
- case: "shape";
- } | {
- /**
- *
- * Fixed point of interest: spot marker, waypoint, checkpoint, 2525
- * symbol, or custom icon. See Marker.
- *
- * @generated from field: meshtastic.Marker marker = 35;
- */
- value: Marker;
- case: "marker";
- } | {
- /**
- *
- * Range and bearing measurement line. See RangeAndBearing.
- *
- * @generated from field: meshtastic.RangeAndBearing rab = 36;
- */
- value: RangeAndBearing;
- case: "rab";
- } | {
- /**
- *
- * Named route with ordered waypoints and control points. See Route.
- *
- * @generated from field: meshtastic.Route route = 37;
- */
- value: Route;
- case: "route";
- } | {
- /**
- *
- * 9-line MEDEVAC request. See CasevacReport.
- *
- * @generated from field: meshtastic.CasevacReport casevac = 38;
- */
- value: CasevacReport;
- case: "casevac";
- } | {
- /**
- *
- * Emergency beacon / 911 alert. See EmergencyAlert.
- *
- * @generated from field: meshtastic.EmergencyAlert emergency = 39;
- */
- value: EmergencyAlert;
- case: "emergency";
- } | {
- /**
- *
- * Task / engage request. See TaskRequest.
- *
- * @generated from field: meshtastic.TaskRequest task = 40;
- */
- value: TaskRequest;
- case: "task";
- } | {
- /**
- *
- * TAKTALK chat message (CoT type m-t-t). See TakTalkMessage.
- * Voice audio itself rides UDP/RTP outside the mesh; this carries the
- * text envelope plus a from_voice marker for receiver UX.
- *
- * @generated from field: meshtastic.TakTalkMessage taktalk = 41;
- */
- value: TakTalkMessage;
- case: "taktalk";
- } | {
- /**
- *
- * TAKTALK room/membership broadcast (CoT type y-). See TakTalkRoomData.
- * Resolves room UUIDs (used in TakTalkMessage.chatroom_id and
- * GeoChat.room_id) to display name + roster on receivers.
- *
- * @generated from field: meshtastic.TakTalkRoomData taktalk_room = 42;
- */
- value: TakTalkRoomData;
- case: "taktalkRoom";
- } | { case: undefined; value?: undefined };
+ payloadVariant:
+ | {
+ /**
+ *
+ * ATAK GeoChat message
+ *
+ * @generated from field: meshtastic.GeoChat chat = 31;
+ */
+ value: GeoChat;
+ case: "chat";
+ }
+ | {
+ /**
+ *
+ * Aircraft track data (ADS-B, military air)
+ *
+ * @generated from field: meshtastic.AircraftTrack aircraft = 32;
+ */
+ value: AircraftTrack;
+ case: "aircraft";
+ }
+ | {
+ /**
+ *
+ * Generic CoT detail XML for unmapped types. Kept as a fallback for CoT
+ * types not yet promoted to a typed variant; drawings, markers, ranging
+ * tools, and routes have dedicated variants below and should not land here.
+ *
+ * @generated from field: bytes raw_detail = 33;
+ */
+ value: Uint8Array;
+ case: "rawDetail";
+ }
+ | {
+ /**
+ *
+ * User-drawn tactical graphic: circle, rectangle, polygon, polyline,
+ * telestration, ranging circle, or bullseye. See DrawnShape.
+ *
+ * @generated from field: meshtastic.DrawnShape shape = 34;
+ */
+ value: DrawnShape;
+ case: "shape";
+ }
+ | {
+ /**
+ *
+ * Fixed point of interest: spot marker, waypoint, checkpoint, 2525
+ * symbol, or custom icon. See Marker.
+ *
+ * @generated from field: meshtastic.Marker marker = 35;
+ */
+ value: Marker;
+ case: "marker";
+ }
+ | {
+ /**
+ *
+ * Range and bearing measurement line. See RangeAndBearing.
+ *
+ * @generated from field: meshtastic.RangeAndBearing rab = 36;
+ */
+ value: RangeAndBearing;
+ case: "rab";
+ }
+ | {
+ /**
+ *
+ * Named route with ordered waypoints and control points. See Route.
+ *
+ * @generated from field: meshtastic.Route route = 37;
+ */
+ value: Route;
+ case: "route";
+ }
+ | {
+ /**
+ *
+ * 9-line MEDEVAC request. See CasevacReport.
+ *
+ * @generated from field: meshtastic.CasevacReport casevac = 38;
+ */
+ value: CasevacReport;
+ case: "casevac";
+ }
+ | {
+ /**
+ *
+ * Emergency beacon / 911 alert. See EmergencyAlert.
+ *
+ * @generated from field: meshtastic.EmergencyAlert emergency = 39;
+ */
+ value: EmergencyAlert;
+ case: "emergency";
+ }
+ | {
+ /**
+ *
+ * Task / engage request. See TaskRequest.
+ *
+ * @generated from field: meshtastic.TaskRequest task = 40;
+ */
+ value: TaskRequest;
+ case: "task";
+ }
+ | {
+ /**
+ *
+ * TAKTALK chat message (CoT type m-t-t). See TakTalkMessage.
+ * Voice audio itself rides UDP/RTP outside the mesh; this carries the
+ * text envelope plus a from_voice marker for receiver UX.
+ *
+ * @generated from field: meshtastic.TakTalkMessage taktalk = 41;
+ */
+ value: TakTalkMessage;
+ case: "taktalk";
+ }
+ | {
+ /**
+ *
+ * TAKTALK room/membership broadcast (CoT type y-). See TakTalkRoomData.
+ * Resolves room UUIDs (used in TakTalkMessage.chatroom_id and
+ * GeoChat.room_id) to display name + roster on receivers.
+ *
+ * @generated from field: meshtastic.TakTalkRoomData taktalk_room = 42;
+ */
+ value: TakTalkRoomData;
+ case: "taktalkRoom";
+ }
+ | { case: undefined; value?: undefined };
};
/**
* Describes the message meshtastic.TAKPacketV2.
* Use `create(TAKPacketV2Schema)` to create a new message.
*/
-export const TAKPacketV2Schema: GenMessage = /*@__PURE__*/
+export const TAKPacketV2Schema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_atak, 21);
/**
@@ -3028,8 +3076,10 @@ export enum Team {
/**
* Describes the enum meshtastic.Team.
*/
-export const TeamSchema: GenEnum = /*@__PURE__*/
- enumDesc(file_meshtastic_atak, 0);
+export const TeamSchema: GenEnum /*@__PURE__*/ = enumDesc(
+ file_meshtastic_atak,
+ 0,
+);
/**
*
@@ -3114,8 +3164,10 @@ export enum MemberRole {
/**
* Describes the enum meshtastic.MemberRole.
*/
-export const MemberRoleSchema: GenEnum = /*@__PURE__*/
- enumDesc(file_meshtastic_atak, 1);
+export const MemberRoleSchema: GenEnum /*@__PURE__*/ = enumDesc(
+ file_meshtastic_atak,
+ 1,
+);
/**
*
@@ -3193,8 +3245,10 @@ export enum CotHow {
/**
* Describes the enum meshtastic.CotHow.
*/
-export const CotHowSchema: GenEnum = /*@__PURE__*/
- enumDesc(file_meshtastic_atak, 2);
+export const CotHowSchema: GenEnum /*@__PURE__*/ = enumDesc(
+ file_meshtastic_atak,
+ 2,
+);
/**
*
@@ -4165,8 +4219,10 @@ export enum CotType {
/**
* Describes the enum meshtastic.CotType.
*/
-export const CotTypeSchema: GenEnum = /*@__PURE__*/
- enumDesc(file_meshtastic_atak, 3);
+export const CotTypeSchema: GenEnum /*@__PURE__*/ = enumDesc(
+ file_meshtastic_atak,
+ 3,
+);
/**
*
@@ -4211,6 +4267,5 @@ export enum GeoPointSource {
/**
* Describes the enum meshtastic.GeoPointSource.
*/
-export const GeoPointSourceSchema: GenEnum = /*@__PURE__*/
+export const GeoPointSourceSchema: GenEnum /*@__PURE__*/ =
enumDesc(file_meshtastic_atak, 4);
-
diff --git a/packages/protobufs/packages/ts/dist/meshtastic/cannedmessages_pb.ts b/packages/protobufs/packages/ts/dist/meshtastic/cannedmessages_pb.ts
index d7c160423..9bad7c131 100644
--- a/packages/protobufs/packages/ts/dist/meshtastic/cannedmessages_pb.ts
+++ b/packages/protobufs/packages/ts/dist/meshtastic/cannedmessages_pb.ts
@@ -1,4 +1,4 @@
-// @generated by protoc-gen-es v2.12.0 with parameter "target=ts"
+// @generated by protoc-gen-es v2.12.1 with parameter "target=ts"
// @generated from file meshtastic/cannedmessages.proto (package meshtastic, syntax proto3)
/* eslint-disable */
@@ -9,8 +9,9 @@ import type { Message } from "@bufbuild/protobuf";
/**
* Describes the file meshtastic/cannedmessages.proto.
*/
-export const file_meshtastic_cannedmessages: GenFile = /*@__PURE__*/
- fileDesc("Ch9tZXNodGFzdGljL2Nhbm5lZG1lc3NhZ2VzLnByb3RvEgptZXNodGFzdGljIi0KGUNhbm5lZE1lc3NhZ2VNb2R1bGVDb25maWcSEAoIbWVzc2FnZXMYASABKAlCbwoUb3JnLm1lc2h0YXN0aWMucHJvdG9CGUNhbm5lZE1lc3NhZ2VDb25maWdQcm90b3NaImdpdGh1Yi5jb20vbWVzaHRhc3RpYy9nby9nZW5lcmF0ZWSqAhRNZXNodGFzdGljLlByb3RvYnVmc7oCAGIGcHJvdG8z");
+export const file_meshtastic_cannedmessages: GenFile /*@__PURE__*/ = fileDesc(
+ "Ch9tZXNodGFzdGljL2Nhbm5lZG1lc3NhZ2VzLnByb3RvEgptZXNodGFzdGljIi0KGUNhbm5lZE1lc3NhZ2VNb2R1bGVDb25maWcSEAoIbWVzc2FnZXMYASABKAlCbwoUb3JnLm1lc2h0YXN0aWMucHJvdG9CGUNhbm5lZE1lc3NhZ2VDb25maWdQcm90b3NaImdpdGh1Yi5jb20vbWVzaHRhc3RpYy9nby9nZW5lcmF0ZWSqAhRNZXNodGFzdGljLlByb3RvYnVmc7oCAGIGcHJvdG8z",
+);
/**
*
@@ -18,20 +19,20 @@ export const file_meshtastic_cannedmessages: GenFile = /*@__PURE__*/
*
* @generated from message meshtastic.CannedMessageModuleConfig
*/
-export type CannedMessageModuleConfig = Message<"meshtastic.CannedMessageModuleConfig"> & {
- /**
- *
- * Predefined messages for canned message module separated by '|' characters.
- *
- * @generated from field: string messages = 1;
- */
- messages: string;
-};
+export type CannedMessageModuleConfig =
+ Message<"meshtastic.CannedMessageModuleConfig"> & {
+ /**
+ *
+ * Predefined messages for canned message module separated by '|' characters.
+ *
+ * @generated from field: string messages = 1;
+ */
+ messages: string;
+ };
/**
* Describes the message meshtastic.CannedMessageModuleConfig.
* Use `create(CannedMessageModuleConfigSchema)` to create a new message.
*/
-export const CannedMessageModuleConfigSchema: GenMessage = /*@__PURE__*/
+export const CannedMessageModuleConfigSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_cannedmessages, 0);
-
diff --git a/packages/protobufs/packages/ts/dist/meshtastic/channel_pb.ts b/packages/protobufs/packages/ts/dist/meshtastic/channel_pb.ts
index 931366ee7..583a2f504 100644
--- a/packages/protobufs/packages/ts/dist/meshtastic/channel_pb.ts
+++ b/packages/protobufs/packages/ts/dist/meshtastic/channel_pb.ts
@@ -1,18 +1,23 @@
-// @generated by protoc-gen-es v2.12.0 with parameter "target=ts"
+// @generated by protoc-gen-es v2.12.1 with parameter "target=ts"
// @generated from file meshtastic/channel.proto (package meshtastic, syntax proto3)
/* eslint-disable */
-// trunk-ignore(buf-lint/PACKAGE_DIRECTORY_MATCH)
+// trunk-ignore(buf-lint/PACKAGE_DIRECTORY_MATCH)
-import type { GenEnum, GenFile, GenMessage } from "@bufbuild/protobuf/codegenv2";
+import type {
+ GenEnum,
+ GenFile,
+ GenMessage,
+} from "@bufbuild/protobuf/codegenv2";
import { enumDesc, fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2";
import type { Message } from "@bufbuild/protobuf";
/**
* Describes the file meshtastic/channel.proto.
*/
-export const file_meshtastic_channel: GenFile = /*@__PURE__*/
- fileDesc("ChhtZXNodGFzdGljL2NoYW5uZWwucHJvdG8SCm1lc2h0YXN0aWMiuAEKD0NoYW5uZWxTZXR0aW5ncxIXCgtjaGFubmVsX251bRgBIAEoDUICGAESCwoDcHNrGAIgASgMEgwKBG5hbWUYAyABKAkSCgoCaWQYBCABKAcSFgoOdXBsaW5rX2VuYWJsZWQYBSABKAgSGAoQZG93bmxpbmtfZW5hYmxlZBgGIAEoCBIzCg9tb2R1bGVfc2V0dGluZ3MYByABKAsyGi5tZXNodGFzdGljLk1vZHVsZVNldHRpbmdzIj4KDk1vZHVsZVNldHRpbmdzEhoKEnBvc2l0aW9uX3ByZWNpc2lvbhgBIAEoDRIQCghpc19tdXRlZBgCIAEoCCKhAQoHQ2hhbm5lbBINCgVpbmRleBgBIAEoBRItCghzZXR0aW5ncxgCIAEoCzIbLm1lc2h0YXN0aWMuQ2hhbm5lbFNldHRpbmdzEiYKBHJvbGUYAyABKA4yGC5tZXNodGFzdGljLkNoYW5uZWwuUm9sZSIwCgRSb2xlEgwKCERJU0FCTEVEEAASCwoHUFJJTUFSWRABEg0KCVNFQ09OREFSWRACQmMKFG9yZy5tZXNodGFzdGljLnByb3RvQg1DaGFubmVsUHJvdG9zWiJnaXRodWIuY29tL21lc2h0YXN0aWMvZ28vZ2VuZXJhdGVkqgIUTWVzaHRhc3RpYy5Qcm90b2J1ZnO6AgBiBnByb3RvMw");
+export const file_meshtastic_channel: GenFile /*@__PURE__*/ = fileDesc(
+ "ChhtZXNodGFzdGljL2NoYW5uZWwucHJvdG8SCm1lc2h0YXN0aWMiuAEKD0NoYW5uZWxTZXR0aW5ncxIXCgtjaGFubmVsX251bRgBIAEoDUICGAESCwoDcHNrGAIgASgMEgwKBG5hbWUYAyABKAkSCgoCaWQYBCABKAcSFgoOdXBsaW5rX2VuYWJsZWQYBSABKAgSGAoQZG93bmxpbmtfZW5hYmxlZBgGIAEoCBIzCg9tb2R1bGVfc2V0dGluZ3MYByABKAsyGi5tZXNodGFzdGljLk1vZHVsZVNldHRpbmdzIj4KDk1vZHVsZVNldHRpbmdzEhoKEnBvc2l0aW9uX3ByZWNpc2lvbhgBIAEoDRIQCghpc19tdXRlZBgCIAEoCCKhAQoHQ2hhbm5lbBINCgVpbmRleBgBIAEoBRItCghzZXR0aW5ncxgCIAEoCzIbLm1lc2h0YXN0aWMuQ2hhbm5lbFNldHRpbmdzEiYKBHJvbGUYAyABKA4yGC5tZXNodGFzdGljLkNoYW5uZWwuUm9sZSIwCgRSb2xlEgwKCERJU0FCTEVEEAASCwoHUFJJTUFSWRABEg0KCVNFQ09OREFSWRACQmMKFG9yZy5tZXNodGFzdGljLnByb3RvQg1DaGFubmVsUHJvdG9zWiJnaXRodWIuY29tL21lc2h0YXN0aWMvZ28vZ2VuZXJhdGVkqgIUTWVzaHRhc3RpYy5Qcm90b2J1ZnO6AgBiBnByb3RvMw",
+);
/**
*
@@ -123,7 +128,7 @@ export type ChannelSettings = Message<"meshtastic.ChannelSettings"> & {
* Describes the message meshtastic.ChannelSettings.
* Use `create(ChannelSettingsSchema)` to create a new message.
*/
-export const ChannelSettingsSchema: GenMessage = /*@__PURE__*/
+export const ChannelSettingsSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_channel, 0);
/**
@@ -155,7 +160,7 @@ export type ModuleSettings = Message<"meshtastic.ModuleSettings"> & {
* Describes the message meshtastic.ModuleSettings.
* Use `create(ModuleSettingsSchema)` to create a new message.
*/
-export const ModuleSettingsSchema: GenMessage = /*@__PURE__*/
+export const ModuleSettingsSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_channel, 1);
/**
@@ -196,8 +201,10 @@ export type Channel = Message<"meshtastic.Channel"> & {
* Describes the message meshtastic.Channel.
* Use `create(ChannelSchema)` to create a new message.
*/
-export const ChannelSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_meshtastic_channel, 2);
+export const ChannelSchema: GenMessage /*@__PURE__*/ = messageDesc(
+ file_meshtastic_channel,
+ 2,
+);
/**
*
@@ -243,6 +250,8 @@ export enum Channel_Role {
/**
* Describes the enum meshtastic.Channel.Role.
*/
-export const Channel_RoleSchema: GenEnum = /*@__PURE__*/
- enumDesc(file_meshtastic_channel, 2, 0);
-
+export const Channel_RoleSchema: GenEnum /*@__PURE__*/ = enumDesc(
+ file_meshtastic_channel,
+ 2,
+ 0,
+);
diff --git a/packages/protobufs/packages/ts/dist/meshtastic/clientonly_pb.ts b/packages/protobufs/packages/ts/dist/meshtastic/clientonly_pb.ts
index 878ab6638..25ad76828 100644
--- a/packages/protobufs/packages/ts/dist/meshtastic/clientonly_pb.ts
+++ b/packages/protobufs/packages/ts/dist/meshtastic/clientonly_pb.ts
@@ -1,4 +1,4 @@
-// @generated by protoc-gen-es v2.12.0 with parameter "target=ts"
+// @generated by protoc-gen-es v2.12.1 with parameter "target=ts"
// @generated from file meshtastic/clientonly.proto (package meshtastic, syntax proto3)
/* eslint-disable */
@@ -13,8 +13,10 @@ import type { Message } from "@bufbuild/protobuf";
/**
* Describes the file meshtastic/clientonly.proto.
*/
-export const file_meshtastic_clientonly: GenFile = /*@__PURE__*/
- fileDesc("ChttZXNodGFzdGljL2NsaWVudG9ubHkucHJvdG8SCm1lc2h0YXN0aWMiqQMKDURldmljZVByb2ZpbGUSFgoJbG9uZ19uYW1lGAEgASgJSACIAQESFwoKc2hvcnRfbmFtZRgCIAEoCUgBiAEBEhgKC2NoYW5uZWxfdXJsGAMgASgJSAKIAQESLAoGY29uZmlnGAQgASgLMhcubWVzaHRhc3RpYy5Mb2NhbENvbmZpZ0gDiAEBEjkKDW1vZHVsZV9jb25maWcYBSABKAsyHS5tZXNodGFzdGljLkxvY2FsTW9kdWxlQ29uZmlnSASIAQESMQoOZml4ZWRfcG9zaXRpb24YBiABKAsyFC5tZXNodGFzdGljLlBvc2l0aW9uSAWIAQESFQoIcmluZ3RvbmUYByABKAlIBogBARIcCg9jYW5uZWRfbWVzc2FnZXMYCCABKAlIB4gBAUIMCgpfbG9uZ19uYW1lQg0KC19zaG9ydF9uYW1lQg4KDF9jaGFubmVsX3VybEIJCgdfY29uZmlnQhAKDl9tb2R1bGVfY29uZmlnQhEKD19maXhlZF9wb3NpdGlvbkILCglfcmluZ3RvbmVCEgoQX2Nhbm5lZF9tZXNzYWdlc0JmChRvcmcubWVzaHRhc3RpYy5wcm90b0IQQ2xpZW50T25seVByb3Rvc1oiZ2l0aHViLmNvbS9tZXNodGFzdGljL2dvL2dlbmVyYXRlZKoCFE1lc2h0YXN0aWMuUHJvdG9idWZzugIAYgZwcm90bzM", [file_meshtastic_localonly, file_meshtastic_mesh]);
+export const file_meshtastic_clientonly: GenFile /*@__PURE__*/ = fileDesc(
+ "ChttZXNodGFzdGljL2NsaWVudG9ubHkucHJvdG8SCm1lc2h0YXN0aWMiqQMKDURldmljZVByb2ZpbGUSFgoJbG9uZ19uYW1lGAEgASgJSACIAQESFwoKc2hvcnRfbmFtZRgCIAEoCUgBiAEBEhgKC2NoYW5uZWxfdXJsGAMgASgJSAKIAQESLAoGY29uZmlnGAQgASgLMhcubWVzaHRhc3RpYy5Mb2NhbENvbmZpZ0gDiAEBEjkKDW1vZHVsZV9jb25maWcYBSABKAsyHS5tZXNodGFzdGljLkxvY2FsTW9kdWxlQ29uZmlnSASIAQESMQoOZml4ZWRfcG9zaXRpb24YBiABKAsyFC5tZXNodGFzdGljLlBvc2l0aW9uSAWIAQESFQoIcmluZ3RvbmUYByABKAlIBogBARIcCg9jYW5uZWRfbWVzc2FnZXMYCCABKAlIB4gBAUIMCgpfbG9uZ19uYW1lQg0KC19zaG9ydF9uYW1lQg4KDF9jaGFubmVsX3VybEIJCgdfY29uZmlnQhAKDl9tb2R1bGVfY29uZmlnQhEKD19maXhlZF9wb3NpdGlvbkILCglfcmluZ3RvbmVCEgoQX2Nhbm5lZF9tZXNzYWdlc0JmChRvcmcubWVzaHRhc3RpYy5wcm90b0IQQ2xpZW50T25seVByb3Rvc1oiZ2l0aHViLmNvbS9tZXNodGFzdGljL2dvL2dlbmVyYXRlZKoCFE1lc2h0YXN0aWMuUHJvdG9idWZzugIAYgZwcm90bzM",
+ [file_meshtastic_localonly, file_meshtastic_mesh],
+);
/**
*
@@ -93,6 +95,5 @@ export type DeviceProfile = Message<"meshtastic.DeviceProfile"> & {
* Describes the message meshtastic.DeviceProfile.
* Use `create(DeviceProfileSchema)` to create a new message.
*/
-export const DeviceProfileSchema: GenMessage = /*@__PURE__*/
+export const DeviceProfileSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_clientonly, 0);
-
diff --git a/packages/protobufs/packages/ts/dist/meshtastic/config_pb.ts b/packages/protobufs/packages/ts/dist/meshtastic/config_pb.ts
index 0b8be50a2..74f637349 100644
--- a/packages/protobufs/packages/ts/dist/meshtastic/config_pb.ts
+++ b/packages/protobufs/packages/ts/dist/meshtastic/config_pb.ts
@@ -1,8 +1,12 @@
-// @generated by protoc-gen-es v2.12.0 with parameter "target=ts"
+// @generated by protoc-gen-es v2.12.1 with parameter "target=ts"
// @generated from file meshtastic/config.proto (package meshtastic, syntax proto3)
/* eslint-disable */
-import type { GenEnum, GenFile, GenMessage } from "@bufbuild/protobuf/codegenv2";
+import type {
+ GenEnum,
+ GenFile,
+ GenMessage,
+} from "@bufbuild/protobuf/codegenv2";
import { enumDesc, fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2";
import type { DeviceUIConfig } from "./device_ui_pb";
import { file_meshtastic_device_ui } from "./device_ui_pb";
@@ -11,8 +15,10 @@ import type { Message } from "@bufbuild/protobuf";
/**
* Describes the file meshtastic/config.proto.
*/
-export const file_meshtastic_config: GenFile = /*@__PURE__*/
- fileDesc("ChdtZXNodGFzdGljL2NvbmZpZy5wcm90bxIKbWVzaHRhc3RpYyLlLAoGQ29uZmlnEjEKBmRldmljZRgBIAEoCzIfLm1lc2h0YXN0aWMuQ29uZmlnLkRldmljZUNvbmZpZ0gAEjUKCHBvc2l0aW9uGAIgASgLMiEubWVzaHRhc3RpYy5Db25maWcuUG9zaXRpb25Db25maWdIABIvCgVwb3dlchgDIAEoCzIeLm1lc2h0YXN0aWMuQ29uZmlnLlBvd2VyQ29uZmlnSAASMwoHbmV0d29yaxgEIAEoCzIgLm1lc2h0YXN0aWMuQ29uZmlnLk5ldHdvcmtDb25maWdIABIzCgdkaXNwbGF5GAUgASgLMiAubWVzaHRhc3RpYy5Db25maWcuRGlzcGxheUNvbmZpZ0gAEi0KBGxvcmEYBiABKAsyHS5tZXNodGFzdGljLkNvbmZpZy5Mb1JhQ29uZmlnSAASNwoJYmx1ZXRvb3RoGAcgASgLMiIubWVzaHRhc3RpYy5Db25maWcuQmx1ZXRvb3RoQ29uZmlnSAASNQoIc2VjdXJpdHkYCCABKAsyIS5tZXNodGFzdGljLkNvbmZpZy5TZWN1cml0eUNvbmZpZ0gAEjkKCnNlc3Npb25rZXkYCSABKAsyIy5tZXNodGFzdGljLkNvbmZpZy5TZXNzaW9ua2V5Q29uZmlnSAASLwoJZGV2aWNlX3VpGAogASgLMhoubWVzaHRhc3RpYy5EZXZpY2VVSUNvbmZpZ0gAGvYGCgxEZXZpY2VDb25maWcSMgoEcm9sZRgBIAEoDjIkLm1lc2h0YXN0aWMuQ29uZmlnLkRldmljZUNvbmZpZy5Sb2xlEhoKDnNlcmlhbF9lbmFibGVkGAIgASgIQgIYARITCgtidXR0b25fZ3BpbxgEIAEoDRITCgtidXp6ZXJfZ3BpbxgFIAEoDRJJChByZWJyb2FkY2FzdF9tb2RlGAYgASgOMi8ubWVzaHRhc3RpYy5Db25maWcuRGV2aWNlQ29uZmlnLlJlYnJvYWRjYXN0TW9kZRIgChhub2RlX2luZm9fYnJvYWRjYXN0X3NlY3MYByABKA0SIgoaZG91YmxlX3RhcF9hc19idXR0b25fcHJlc3MYCCABKAgSFgoKaXNfbWFuYWdlZBgJIAEoCEICGAESHAoUZGlzYWJsZV90cmlwbGVfY2xpY2sYCiABKAgSDQoFdHpkZWYYCyABKAkSHgoWbGVkX2hlYXJ0YmVhdF9kaXNhYmxlZBgMIAEoCBI/CgtidXp6ZXJfbW9kZRgNIAEoDjIqLm1lc2h0YXN0aWMuQ29uZmlnLkRldmljZUNvbmZpZy5CdXp6ZXJNb2RlItQBCgRSb2xlEgoKBkNMSUVOVBAAEg8KC0NMSUVOVF9NVVRFEAESCgoGUk9VVEVSEAISFQoNUk9VVEVSX0NMSUVOVBADGgIIARIQCghSRVBFQVRFUhAEGgIIARILCgdUUkFDS0VSEAUSCgoGU0VOU09SEAYSBwoDVEFLEAcSEQoNQ0xJRU5UX0hJRERFThAIEhIKDkxPU1RfQU5EX0ZPVU5EEAkSDwoLVEFLX1RSQUNLRVIQChIPCgtST1VURVJfTEFURRALEg8KC0NMSUVOVF9CQVNFEAwicwoPUmVicm9hZGNhc3RNb2RlEgcKA0FMTBAAEhUKEUFMTF9TS0lQX0RFQ09ESU5HEAESDgoKTE9DQUxfT05MWRACEg4KCktOT1dOX09OTFkQAxIICgROT05FEAQSFgoSQ09SRV9QT1JUTlVNU19PTkxZEAUiaQoKQnV6emVyTW9kZRIPCgtBTExfRU5BQkxFRBAAEgwKCERJU0FCTEVEEAESFgoSTk9USUZJQ0FUSU9OU19PTkxZEAISDwoLU1lTVEVNX09OTFkQAxITCg9ESVJFQ1RfTVNHX09OTFkQBBqRBQoOUG9zaXRpb25Db25maWcSHwoXcG9zaXRpb25fYnJvYWRjYXN0X3NlY3MYASABKA0SKAogcG9zaXRpb25fYnJvYWRjYXN0X3NtYXJ0X2VuYWJsZWQYAiABKAgSFgoOZml4ZWRfcG9zaXRpb24YAyABKAgSFwoLZ3BzX2VuYWJsZWQYBCABKAhCAhgBEhsKE2dwc191cGRhdGVfaW50ZXJ2YWwYBSABKA0SHAoQZ3BzX2F0dGVtcHRfdGltZRgGIAEoDUICGAESFgoOcG9zaXRpb25fZmxhZ3MYByABKA0SDwoHcnhfZ3BpbxgIIAEoDRIPCgd0eF9ncGlvGAkgASgNEigKIGJyb2FkY2FzdF9zbWFydF9taW5pbXVtX2Rpc3RhbmNlGAogASgNEi0KJWJyb2FkY2FzdF9zbWFydF9taW5pbXVtX2ludGVydmFsX3NlY3MYCyABKA0SEwoLZ3BzX2VuX2dwaW8YDCABKA0SOwoIZ3BzX21vZGUYDSABKA4yKS5tZXNodGFzdGljLkNvbmZpZy5Qb3NpdGlvbkNvbmZpZy5HcHNNb2RlIqsBCg1Qb3NpdGlvbkZsYWdzEgkKBVVOU0VUEAASDAoIQUxUSVRVREUQARIQCgxBTFRJVFVERV9NU0wQAhIWChJHRU9JREFMX1NFUEFSQVRJT04QBBIHCgNET1AQCBIJCgVIVkRPUBAQEg0KCVNBVElOVklFVxAgEgoKBlNFUV9OTxBAEg4KCVRJTUVTVEFNUBCAARIMCgdIRUFESU5HEIACEgoKBVNQRUVEEIAEIjUKB0dwc01vZGUSDAoIRElTQUJMRUQQABILCgdFTkFCTEVEEAESDwoLTk9UX1BSRVNFTlQQAhqEAgoLUG93ZXJDb25maWcSFwoPaXNfcG93ZXJfc2F2aW5nGAEgASgIEiYKHm9uX2JhdHRlcnlfc2h1dGRvd25fYWZ0ZXJfc2VjcxgCIAEoDRIfChdhZGNfbXVsdGlwbGllcl9vdmVycmlkZRgDIAEoAhIbChN3YWl0X2JsdWV0b290aF9zZWNzGAQgASgNEhAKCHNkc19zZWNzGAYgASgNEg8KB2xzX3NlY3MYByABKA0SFQoNbWluX3dha2Vfc2VjcxgIIAEoDRIiChpkZXZpY2VfYmF0dGVyeV9pbmFfYWRkcmVzcxgJIAEoDRIYChBwb3dlcm1vbl9lbmFibGVzGCAgASgEGuUDCg1OZXR3b3JrQ29uZmlnEhQKDHdpZmlfZW5hYmxlZBgBIAEoCBIRCgl3aWZpX3NzaWQYAyABKAkSEAoId2lmaV9wc2sYBCABKAkSEgoKbnRwX3NlcnZlchgFIAEoCRITCgtldGhfZW5hYmxlZBgGIAEoCBJCCgxhZGRyZXNzX21vZGUYByABKA4yLC5tZXNodGFzdGljLkNvbmZpZy5OZXR3b3JrQ29uZmlnLkFkZHJlc3NNb2RlEkAKC2lwdjRfY29uZmlnGAggASgLMisubWVzaHRhc3RpYy5Db25maWcuTmV0d29ya0NvbmZpZy5JcFY0Q29uZmlnEhYKDnJzeXNsb2dfc2VydmVyGAkgASgJEhkKEWVuYWJsZWRfcHJvdG9jb2xzGAogASgNEhQKDGlwdjZfZW5hYmxlZBgLIAEoCBpGCgpJcFY0Q29uZmlnEgoKAmlwGAEgASgHEg8KB2dhdGV3YXkYAiABKAcSDgoGc3VibmV0GAMgASgHEgsKA2RucxgEIAEoByIjCgtBZGRyZXNzTW9kZRIICgRESENQEAASCgoGU1RBVElDEAEiNAoNUHJvdG9jb2xGbGFncxIQCgxOT19CUk9BRENBU1QQABIRCg1VRFBfQlJPQURDQVNUEAEawggKDURpc3BsYXlDb25maWcSFgoOc2NyZWVuX29uX3NlY3MYASABKA0SVgoKZ3BzX2Zvcm1hdBgCIAEoDjI+Lm1lc2h0YXN0aWMuQ29uZmlnLkRpc3BsYXlDb25maWcuRGVwcmVjYXRlZEdwc0Nvb3JkaW5hdGVGb3JtYXRCAhgBEiEKGWF1dG9fc2NyZWVuX2Nhcm91c2VsX3NlY3MYAyABKA0SHQoRY29tcGFzc19ub3J0aF90b3AYBCABKAhCAhgBEhMKC2ZsaXBfc2NyZWVuGAUgASgIEjwKBXVuaXRzGAYgASgOMi0ubWVzaHRhc3RpYy5Db25maWcuRGlzcGxheUNvbmZpZy5EaXNwbGF5VW5pdHMSNwoEb2xlZBgHIAEoDjIpLm1lc2h0YXN0aWMuQ29uZmlnLkRpc3BsYXlDb25maWcuT2xlZFR5cGUSQQoLZGlzcGxheW1vZGUYCCABKA4yLC5tZXNodGFzdGljLkNvbmZpZy5EaXNwbGF5Q29uZmlnLkRpc3BsYXlNb2RlEhQKDGhlYWRpbmdfYm9sZBgJIAEoCBIdChV3YWtlX29uX3RhcF9vcl9tb3Rpb24YCiABKAgSUAoTY29tcGFzc19vcmllbnRhdGlvbhgLIAEoDjIzLm1lc2h0YXN0aWMuQ29uZmlnLkRpc3BsYXlDb25maWcuQ29tcGFzc09yaWVudGF0aW9uEhUKDXVzZV8xMmhfY2xvY2sYDCABKAgSGgoSdXNlX2xvbmdfbm9kZV9uYW1lGA0gASgIEh4KFmVuYWJsZV9tZXNzYWdlX2J1YmJsZXMYDiABKAgiKwodRGVwcmVjYXRlZEdwc0Nvb3JkaW5hdGVGb3JtYXQSCgoGVU5VU0VEEAAiKAoMRGlzcGxheVVuaXRzEgoKBk1FVFJJQxAAEgwKCElNUEVSSUFMEAEifwoIT2xlZFR5cGUSDQoJT0xFRF9BVVRPEAASEAoMT0xFRF9TU0QxMzA2EAESDwoLT0xFRF9TSDExMDYQAhIPCgtPTEVEX1NIMTEwNxADEhcKE09MRURfU0gxMTA3XzEyOF8xMjgQBBIXChNPTEVEX1NIMTEwN19ST1RBVEVEEAUiQQoLRGlzcGxheU1vZGUSCwoHREVGQVVMVBAAEgwKCFRXT0NPTE9SEAESDAoISU5WRVJURUQQAhIJCgVDT0xPUhADIroBChJDb21wYXNzT3JpZW50YXRpb24SDQoJREVHUkVFU18wEAASDgoKREVHUkVFU185MBABEg8KC0RFR1JFRVNfMTgwEAISDwoLREVHUkVFU18yNzAQAxIWChJERUdSRUVTXzBfSU5WRVJURUQQBBIXChNERUdSRUVTXzkwX0lOVkVSVEVEEAUSGAoUREVHUkVFU18xODBfSU5WRVJURUQQBhIYChRERUdSRUVTXzI3MF9JTlZFUlRFRBAHGvkKCgpMb1JhQ29uZmlnEhIKCnVzZV9wcmVzZXQYASABKAgSPwoMbW9kZW1fcHJlc2V0GAIgASgOMikubWVzaHRhc3RpYy5Db25maWcuTG9SYUNvbmZpZy5Nb2RlbVByZXNldBIRCgliYW5kd2lkdGgYAyABKA0SFQoNc3ByZWFkX2ZhY3RvchgEIAEoDRITCgtjb2RpbmdfcmF0ZRgFIAEoDRIYChBmcmVxdWVuY3lfb2Zmc2V0GAYgASgCEjgKBnJlZ2lvbhgHIAEoDjIoLm1lc2h0YXN0aWMuQ29uZmlnLkxvUmFDb25maWcuUmVnaW9uQ29kZRIRCglob3BfbGltaXQYCCABKA0SEgoKdHhfZW5hYmxlZBgJIAEoCBIQCgh0eF9wb3dlchgKIAEoBRITCgtjaGFubmVsX251bRgLIAEoDRIbChNvdmVycmlkZV9kdXR5X2N5Y2xlGAwgASgIEh4KFnN4MTI2eF9yeF9ib29zdGVkX2dhaW4YDSABKAgSGgoSb3ZlcnJpZGVfZnJlcXVlbmN5GA4gASgCEhcKD3BhX2Zhbl9kaXNhYmxlZBgPIAEoCBIXCg9pZ25vcmVfaW5jb21pbmcYZyADKA0SEwoLaWdub3JlX21xdHQYaCABKAgSGQoRY29uZmlnX29rX3RvX21xdHQYaSABKAgSQAoMZmVtX2xuYV9tb2RlGGogASgOMioubWVzaHRhc3RpYy5Db25maWcuTG9SYUNvbmZpZy5GRU1fTE5BX01vZGUSFwoPc2VyaWFsX2hhbF9vbmx5GGsgASgIIsQDCgpSZWdpb25Db2RlEgkKBVVOU0VUEAASBgoCVVMQARIKCgZFVV80MzMQAhIKCgZFVV84NjgQAxIGCgJDThAEEgYKAkpQEAUSBwoDQU5aEAYSBgoCS1IQBxIGCgJUVxAIEgYKAlJVEAkSBgoCSU4QChIKCgZOWl84NjUQCxIGCgJUSBAMEgsKB0xPUkFfMjQQDRIKCgZVQV80MzMQDhIKCgZVQV84NjgQDxIKCgZNWV80MzMQEBIKCgZNWV85MTkQERIKCgZTR185MjMQEhIKCgZQSF80MzMQExIKCgZQSF84NjgQFBIKCgZQSF85MTUQFRILCgdBTlpfNDMzEBYSCgoGS1pfNDMzEBcSCgoGS1pfODYzEBgSCgoGTlBfODY1EBkSCgoGQlJfOTAyEBoSCwoHSVRVMV8yTRAbEgsKB0lUVTJfMk0QHBIKCgZFVV84NjYQHRIKCgZFVV84NzQQHhIKCgZFVV85MTcQHxIMCghFVV9OXzg2OBAgEgsKB0lUVTNfMk0QIRINCglJVFUxXzcwQ00QIhINCglJVFUyXzcwQ00QIxINCglJVFUzXzcwQ00QJBIOCgpJVFUyXzEyNUNNECUimwIKC01vZGVtUHJlc2V0Eg0KCUxPTkdfRkFTVBAAEhEKCUxPTkdfU0xPVxABGgIIARIWCg5WRVJZX0xPTkdfU0xPVxACGgIIARIPCgtNRURJVU1fU0xPVxADEg8KC01FRElVTV9GQVNUEAQSDgoKU0hPUlRfU0xPVxAFEg4KClNIT1JUX0ZBU1QQBhIRCg1MT05HX01PREVSQVRFEAcSDwoLU0hPUlRfVFVSQk8QCBIOCgpMT05HX1RVUkJPEAkSDQoJTElURV9GQVNUEAoSDQoJTElURV9TTE9XEAsSDwoLTkFSUk9XX0ZBU1QQDBIPCgtOQVJST1dfU0xPVxANEg0KCVRJTllfRkFTVBAOEg0KCVRJTllfU0xPVxAPIjoKDEZFTV9MTkFfTW9kZRIMCghESVNBQkxFRBAAEgsKB0VOQUJMRUQQARIPCgtOT1RfUFJFU0VOVBACGq0BCg9CbHVldG9vdGhDb25maWcSDwoHZW5hYmxlZBgBIAEoCBI8CgRtb2RlGAIgASgOMi4ubWVzaHRhc3RpYy5Db25maWcuQmx1ZXRvb3RoQ29uZmlnLlBhaXJpbmdNb2RlEhEKCWZpeGVkX3BpbhgDIAEoDSI4CgtQYWlyaW5nTW9kZRIOCgpSQU5ET01fUElOEAASDQoJRklYRURfUElOEAESCgoGTk9fUElOEAIatgEKDlNlY3VyaXR5Q29uZmlnEhIKCnB1YmxpY19rZXkYASABKAwSEwoLcHJpdmF0ZV9rZXkYAiABKAwSEQoJYWRtaW5fa2V5GAMgAygMEhIKCmlzX21hbmFnZWQYBCABKAgSFgoOc2VyaWFsX2VuYWJsZWQYBSABKAgSHQoVZGVidWdfbG9nX2FwaV9lbmFibGVkGAYgASgIEh0KFWFkbWluX2NoYW5uZWxfZW5hYmxlZBgIIAEoCBoSChBTZXNzaW9ua2V5Q29uZmlnQhEKD3BheWxvYWRfdmFyaWFudEJiChRvcmcubWVzaHRhc3RpYy5wcm90b0IMQ29uZmlnUHJvdG9zWiJnaXRodWIuY29tL21lc2h0YXN0aWMvZ28vZ2VuZXJhdGVkqgIUTWVzaHRhc3RpYy5Qcm90b2J1ZnO6AgBiBnByb3RvMw", [file_meshtastic_device_ui]);
+export const file_meshtastic_config: GenFile /*@__PURE__*/ = fileDesc(
+ "ChdtZXNodGFzdGljL2NvbmZpZy5wcm90bxIKbWVzaHRhc3RpYyLlLAoGQ29uZmlnEjEKBmRldmljZRgBIAEoCzIfLm1lc2h0YXN0aWMuQ29uZmlnLkRldmljZUNvbmZpZ0gAEjUKCHBvc2l0aW9uGAIgASgLMiEubWVzaHRhc3RpYy5Db25maWcuUG9zaXRpb25Db25maWdIABIvCgVwb3dlchgDIAEoCzIeLm1lc2h0YXN0aWMuQ29uZmlnLlBvd2VyQ29uZmlnSAASMwoHbmV0d29yaxgEIAEoCzIgLm1lc2h0YXN0aWMuQ29uZmlnLk5ldHdvcmtDb25maWdIABIzCgdkaXNwbGF5GAUgASgLMiAubWVzaHRhc3RpYy5Db25maWcuRGlzcGxheUNvbmZpZ0gAEi0KBGxvcmEYBiABKAsyHS5tZXNodGFzdGljLkNvbmZpZy5Mb1JhQ29uZmlnSAASNwoJYmx1ZXRvb3RoGAcgASgLMiIubWVzaHRhc3RpYy5Db25maWcuQmx1ZXRvb3RoQ29uZmlnSAASNQoIc2VjdXJpdHkYCCABKAsyIS5tZXNodGFzdGljLkNvbmZpZy5TZWN1cml0eUNvbmZpZ0gAEjkKCnNlc3Npb25rZXkYCSABKAsyIy5tZXNodGFzdGljLkNvbmZpZy5TZXNzaW9ua2V5Q29uZmlnSAASLwoJZGV2aWNlX3VpGAogASgLMhoubWVzaHRhc3RpYy5EZXZpY2VVSUNvbmZpZ0gAGvYGCgxEZXZpY2VDb25maWcSMgoEcm9sZRgBIAEoDjIkLm1lc2h0YXN0aWMuQ29uZmlnLkRldmljZUNvbmZpZy5Sb2xlEhoKDnNlcmlhbF9lbmFibGVkGAIgASgIQgIYARITCgtidXR0b25fZ3BpbxgEIAEoDRITCgtidXp6ZXJfZ3BpbxgFIAEoDRJJChByZWJyb2FkY2FzdF9tb2RlGAYgASgOMi8ubWVzaHRhc3RpYy5Db25maWcuRGV2aWNlQ29uZmlnLlJlYnJvYWRjYXN0TW9kZRIgChhub2RlX2luZm9fYnJvYWRjYXN0X3NlY3MYByABKA0SIgoaZG91YmxlX3RhcF9hc19idXR0b25fcHJlc3MYCCABKAgSFgoKaXNfbWFuYWdlZBgJIAEoCEICGAESHAoUZGlzYWJsZV90cmlwbGVfY2xpY2sYCiABKAgSDQoFdHpkZWYYCyABKAkSHgoWbGVkX2hlYXJ0YmVhdF9kaXNhYmxlZBgMIAEoCBI/CgtidXp6ZXJfbW9kZRgNIAEoDjIqLm1lc2h0YXN0aWMuQ29uZmlnLkRldmljZUNvbmZpZy5CdXp6ZXJNb2RlItQBCgRSb2xlEgoKBkNMSUVOVBAAEg8KC0NMSUVOVF9NVVRFEAESCgoGUk9VVEVSEAISFQoNUk9VVEVSX0NMSUVOVBADGgIIARIQCghSRVBFQVRFUhAEGgIIARILCgdUUkFDS0VSEAUSCgoGU0VOU09SEAYSBwoDVEFLEAcSEQoNQ0xJRU5UX0hJRERFThAIEhIKDkxPU1RfQU5EX0ZPVU5EEAkSDwoLVEFLX1RSQUNLRVIQChIPCgtST1VURVJfTEFURRALEg8KC0NMSUVOVF9CQVNFEAwicwoPUmVicm9hZGNhc3RNb2RlEgcKA0FMTBAAEhUKEUFMTF9TS0lQX0RFQ09ESU5HEAESDgoKTE9DQUxfT05MWRACEg4KCktOT1dOX09OTFkQAxIICgROT05FEAQSFgoSQ09SRV9QT1JUTlVNU19PTkxZEAUiaQoKQnV6emVyTW9kZRIPCgtBTExfRU5BQkxFRBAAEgwKCERJU0FCTEVEEAESFgoSTk9USUZJQ0FUSU9OU19PTkxZEAISDwoLU1lTVEVNX09OTFkQAxITCg9ESVJFQ1RfTVNHX09OTFkQBBqRBQoOUG9zaXRpb25Db25maWcSHwoXcG9zaXRpb25fYnJvYWRjYXN0X3NlY3MYASABKA0SKAogcG9zaXRpb25fYnJvYWRjYXN0X3NtYXJ0X2VuYWJsZWQYAiABKAgSFgoOZml4ZWRfcG9zaXRpb24YAyABKAgSFwoLZ3BzX2VuYWJsZWQYBCABKAhCAhgBEhsKE2dwc191cGRhdGVfaW50ZXJ2YWwYBSABKA0SHAoQZ3BzX2F0dGVtcHRfdGltZRgGIAEoDUICGAESFgoOcG9zaXRpb25fZmxhZ3MYByABKA0SDwoHcnhfZ3BpbxgIIAEoDRIPCgd0eF9ncGlvGAkgASgNEigKIGJyb2FkY2FzdF9zbWFydF9taW5pbXVtX2Rpc3RhbmNlGAogASgNEi0KJWJyb2FkY2FzdF9zbWFydF9taW5pbXVtX2ludGVydmFsX3NlY3MYCyABKA0SEwoLZ3BzX2VuX2dwaW8YDCABKA0SOwoIZ3BzX21vZGUYDSABKA4yKS5tZXNodGFzdGljLkNvbmZpZy5Qb3NpdGlvbkNvbmZpZy5HcHNNb2RlIqsBCg1Qb3NpdGlvbkZsYWdzEgkKBVVOU0VUEAASDAoIQUxUSVRVREUQARIQCgxBTFRJVFVERV9NU0wQAhIWChJHRU9JREFMX1NFUEFSQVRJT04QBBIHCgNET1AQCBIJCgVIVkRPUBAQEg0KCVNBVElOVklFVxAgEgoKBlNFUV9OTxBAEg4KCVRJTUVTVEFNUBCAARIMCgdIRUFESU5HEIACEgoKBVNQRUVEEIAEIjUKB0dwc01vZGUSDAoIRElTQUJMRUQQABILCgdFTkFCTEVEEAESDwoLTk9UX1BSRVNFTlQQAhqEAgoLUG93ZXJDb25maWcSFwoPaXNfcG93ZXJfc2F2aW5nGAEgASgIEiYKHm9uX2JhdHRlcnlfc2h1dGRvd25fYWZ0ZXJfc2VjcxgCIAEoDRIfChdhZGNfbXVsdGlwbGllcl9vdmVycmlkZRgDIAEoAhIbChN3YWl0X2JsdWV0b290aF9zZWNzGAQgASgNEhAKCHNkc19zZWNzGAYgASgNEg8KB2xzX3NlY3MYByABKA0SFQoNbWluX3dha2Vfc2VjcxgIIAEoDRIiChpkZXZpY2VfYmF0dGVyeV9pbmFfYWRkcmVzcxgJIAEoDRIYChBwb3dlcm1vbl9lbmFibGVzGCAgASgEGuUDCg1OZXR3b3JrQ29uZmlnEhQKDHdpZmlfZW5hYmxlZBgBIAEoCBIRCgl3aWZpX3NzaWQYAyABKAkSEAoId2lmaV9wc2sYBCABKAkSEgoKbnRwX3NlcnZlchgFIAEoCRITCgtldGhfZW5hYmxlZBgGIAEoCBJCCgxhZGRyZXNzX21vZGUYByABKA4yLC5tZXNodGFzdGljLkNvbmZpZy5OZXR3b3JrQ29uZmlnLkFkZHJlc3NNb2RlEkAKC2lwdjRfY29uZmlnGAggASgLMisubWVzaHRhc3RpYy5Db25maWcuTmV0d29ya0NvbmZpZy5JcFY0Q29uZmlnEhYKDnJzeXNsb2dfc2VydmVyGAkgASgJEhkKEWVuYWJsZWRfcHJvdG9jb2xzGAogASgNEhQKDGlwdjZfZW5hYmxlZBgLIAEoCBpGCgpJcFY0Q29uZmlnEgoKAmlwGAEgASgHEg8KB2dhdGV3YXkYAiABKAcSDgoGc3VibmV0GAMgASgHEgsKA2RucxgEIAEoByIjCgtBZGRyZXNzTW9kZRIICgRESENQEAASCgoGU1RBVElDEAEiNAoNUHJvdG9jb2xGbGFncxIQCgxOT19CUk9BRENBU1QQABIRCg1VRFBfQlJPQURDQVNUEAEawggKDURpc3BsYXlDb25maWcSFgoOc2NyZWVuX29uX3NlY3MYASABKA0SVgoKZ3BzX2Zvcm1hdBgCIAEoDjI+Lm1lc2h0YXN0aWMuQ29uZmlnLkRpc3BsYXlDb25maWcuRGVwcmVjYXRlZEdwc0Nvb3JkaW5hdGVGb3JtYXRCAhgBEiEKGWF1dG9fc2NyZWVuX2Nhcm91c2VsX3NlY3MYAyABKA0SHQoRY29tcGFzc19ub3J0aF90b3AYBCABKAhCAhgBEhMKC2ZsaXBfc2NyZWVuGAUgASgIEjwKBXVuaXRzGAYgASgOMi0ubWVzaHRhc3RpYy5Db25maWcuRGlzcGxheUNvbmZpZy5EaXNwbGF5VW5pdHMSNwoEb2xlZBgHIAEoDjIpLm1lc2h0YXN0aWMuQ29uZmlnLkRpc3BsYXlDb25maWcuT2xlZFR5cGUSQQoLZGlzcGxheW1vZGUYCCABKA4yLC5tZXNodGFzdGljLkNvbmZpZy5EaXNwbGF5Q29uZmlnLkRpc3BsYXlNb2RlEhQKDGhlYWRpbmdfYm9sZBgJIAEoCBIdChV3YWtlX29uX3RhcF9vcl9tb3Rpb24YCiABKAgSUAoTY29tcGFzc19vcmllbnRhdGlvbhgLIAEoDjIzLm1lc2h0YXN0aWMuQ29uZmlnLkRpc3BsYXlDb25maWcuQ29tcGFzc09yaWVudGF0aW9uEhUKDXVzZV8xMmhfY2xvY2sYDCABKAgSGgoSdXNlX2xvbmdfbm9kZV9uYW1lGA0gASgIEh4KFmVuYWJsZV9tZXNzYWdlX2J1YmJsZXMYDiABKAgiKwodRGVwcmVjYXRlZEdwc0Nvb3JkaW5hdGVGb3JtYXQSCgoGVU5VU0VEEAAiKAoMRGlzcGxheVVuaXRzEgoKBk1FVFJJQxAAEgwKCElNUEVSSUFMEAEifwoIT2xlZFR5cGUSDQoJT0xFRF9BVVRPEAASEAoMT0xFRF9TU0QxMzA2EAESDwoLT0xFRF9TSDExMDYQAhIPCgtPTEVEX1NIMTEwNxADEhcKE09MRURfU0gxMTA3XzEyOF8xMjgQBBIXChNPTEVEX1NIMTEwN19ST1RBVEVEEAUiQQoLRGlzcGxheU1vZGUSCwoHREVGQVVMVBAAEgwKCFRXT0NPTE9SEAESDAoISU5WRVJURUQQAhIJCgVDT0xPUhADIroBChJDb21wYXNzT3JpZW50YXRpb24SDQoJREVHUkVFU18wEAASDgoKREVHUkVFU185MBABEg8KC0RFR1JFRVNfMTgwEAISDwoLREVHUkVFU18yNzAQAxIWChJERUdSRUVTXzBfSU5WRVJURUQQBBIXChNERUdSRUVTXzkwX0lOVkVSVEVEEAUSGAoUREVHUkVFU18xODBfSU5WRVJURUQQBhIYChRERUdSRUVTXzI3MF9JTlZFUlRFRBAHGvkKCgpMb1JhQ29uZmlnEhIKCnVzZV9wcmVzZXQYASABKAgSPwoMbW9kZW1fcHJlc2V0GAIgASgOMikubWVzaHRhc3RpYy5Db25maWcuTG9SYUNvbmZpZy5Nb2RlbVByZXNldBIRCgliYW5kd2lkdGgYAyABKA0SFQoNc3ByZWFkX2ZhY3RvchgEIAEoDRITCgtjb2RpbmdfcmF0ZRgFIAEoDRIYChBmcmVxdWVuY3lfb2Zmc2V0GAYgASgCEjgKBnJlZ2lvbhgHIAEoDjIoLm1lc2h0YXN0aWMuQ29uZmlnLkxvUmFDb25maWcuUmVnaW9uQ29kZRIRCglob3BfbGltaXQYCCABKA0SEgoKdHhfZW5hYmxlZBgJIAEoCBIQCgh0eF9wb3dlchgKIAEoBRITCgtjaGFubmVsX251bRgLIAEoDRIbChNvdmVycmlkZV9kdXR5X2N5Y2xlGAwgASgIEh4KFnN4MTI2eF9yeF9ib29zdGVkX2dhaW4YDSABKAgSGgoSb3ZlcnJpZGVfZnJlcXVlbmN5GA4gASgCEhcKD3BhX2Zhbl9kaXNhYmxlZBgPIAEoCBIXCg9pZ25vcmVfaW5jb21pbmcYZyADKA0SEwoLaWdub3JlX21xdHQYaCABKAgSGQoRY29uZmlnX29rX3RvX21xdHQYaSABKAgSQAoMZmVtX2xuYV9tb2RlGGogASgOMioubWVzaHRhc3RpYy5Db25maWcuTG9SYUNvbmZpZy5GRU1fTE5BX01vZGUSFwoPc2VyaWFsX2hhbF9vbmx5GGsgASgIIsQDCgpSZWdpb25Db2RlEgkKBVVOU0VUEAASBgoCVVMQARIKCgZFVV80MzMQAhIKCgZFVV84NjgQAxIGCgJDThAEEgYKAkpQEAUSBwoDQU5aEAYSBgoCS1IQBxIGCgJUVxAIEgYKAlJVEAkSBgoCSU4QChIKCgZOWl84NjUQCxIGCgJUSBAMEgsKB0xPUkFfMjQQDRIKCgZVQV80MzMQDhIKCgZVQV84NjgQDxIKCgZNWV80MzMQEBIKCgZNWV85MTkQERIKCgZTR185MjMQEhIKCgZQSF80MzMQExIKCgZQSF84NjgQFBIKCgZQSF85MTUQFRILCgdBTlpfNDMzEBYSCgoGS1pfNDMzEBcSCgoGS1pfODYzEBgSCgoGTlBfODY1EBkSCgoGQlJfOTAyEBoSCwoHSVRVMV8yTRAbEgsKB0lUVTJfMk0QHBIKCgZFVV84NjYQHRIKCgZFVV84NzQQHhIKCgZFVV85MTcQHxIMCghFVV9OXzg2OBAgEgsKB0lUVTNfMk0QIRINCglJVFUxXzcwQ00QIhINCglJVFUyXzcwQ00QIxINCglJVFUzXzcwQ00QJBIOCgpJVFUyXzEyNUNNECUimwIKC01vZGVtUHJlc2V0Eg0KCUxPTkdfRkFTVBAAEhEKCUxPTkdfU0xPVxABGgIIARIWCg5WRVJZX0xPTkdfU0xPVxACGgIIARIPCgtNRURJVU1fU0xPVxADEg8KC01FRElVTV9GQVNUEAQSDgoKU0hPUlRfU0xPVxAFEg4KClNIT1JUX0ZBU1QQBhIRCg1MT05HX01PREVSQVRFEAcSDwoLU0hPUlRfVFVSQk8QCBIOCgpMT05HX1RVUkJPEAkSDQoJTElURV9GQVNUEAoSDQoJTElURV9TTE9XEAsSDwoLTkFSUk9XX0ZBU1QQDBIPCgtOQVJST1dfU0xPVxANEg0KCVRJTllfRkFTVBAOEg0KCVRJTllfU0xPVxAPIjoKDEZFTV9MTkFfTW9kZRIMCghESVNBQkxFRBAAEgsKB0VOQUJMRUQQARIPCgtOT1RfUFJFU0VOVBACGq0BCg9CbHVldG9vdGhDb25maWcSDwoHZW5hYmxlZBgBIAEoCBI8CgRtb2RlGAIgASgOMi4ubWVzaHRhc3RpYy5Db25maWcuQmx1ZXRvb3RoQ29uZmlnLlBhaXJpbmdNb2RlEhEKCWZpeGVkX3BpbhgDIAEoDSI4CgtQYWlyaW5nTW9kZRIOCgpSQU5ET01fUElOEAASDQoJRklYRURfUElOEAESCgoGTk9fUElOEAIatgEKDlNlY3VyaXR5Q29uZmlnEhIKCnB1YmxpY19rZXkYASABKAwSEwoLcHJpdmF0ZV9rZXkYAiABKAwSEQoJYWRtaW5fa2V5GAMgAygMEhIKCmlzX21hbmFnZWQYBCABKAgSFgoOc2VyaWFsX2VuYWJsZWQYBSABKAgSHQoVZGVidWdfbG9nX2FwaV9lbmFibGVkGAYgASgIEh0KFWFkbWluX2NoYW5uZWxfZW5hYmxlZBgIIAEoCBoSChBTZXNzaW9ua2V5Q29uZmlnQhEKD3BheWxvYWRfdmFyaWFudEJiChRvcmcubWVzaHRhc3RpYy5wcm90b0IMQ29uZmlnUHJvdG9zWiJnaXRodWIuY29tL21lc2h0YXN0aWMvZ28vZ2VuZXJhdGVkqgIUTWVzaHRhc3RpYy5Qcm90b2J1ZnO6AgBiBnByb3RvMw",
+ [file_meshtastic_device_ui],
+);
/**
* @generated from message meshtastic.Config
@@ -24,75 +30,88 @@ export type Config = Message<"meshtastic.Config"> & {
*
* @generated from oneof meshtastic.Config.payload_variant
*/
- payloadVariant: {
- /**
- * @generated from field: meshtastic.Config.DeviceConfig device = 1;
- */
- value: Config_DeviceConfig;
- case: "device";
- } | {
- /**
- * @generated from field: meshtastic.Config.PositionConfig position = 2;
- */
- value: Config_PositionConfig;
- case: "position";
- } | {
- /**
- * @generated from field: meshtastic.Config.PowerConfig power = 3;
- */
- value: Config_PowerConfig;
- case: "power";
- } | {
- /**
- * @generated from field: meshtastic.Config.NetworkConfig network = 4;
- */
- value: Config_NetworkConfig;
- case: "network";
- } | {
- /**
- * @generated from field: meshtastic.Config.DisplayConfig display = 5;
- */
- value: Config_DisplayConfig;
- case: "display";
- } | {
- /**
- * @generated from field: meshtastic.Config.LoRaConfig lora = 6;
- */
- value: Config_LoRaConfig;
- case: "lora";
- } | {
- /**
- * @generated from field: meshtastic.Config.BluetoothConfig bluetooth = 7;
- */
- value: Config_BluetoothConfig;
- case: "bluetooth";
- } | {
- /**
- * @generated from field: meshtastic.Config.SecurityConfig security = 8;
- */
- value: Config_SecurityConfig;
- case: "security";
- } | {
- /**
- * @generated from field: meshtastic.Config.SessionkeyConfig sessionkey = 9;
- */
- value: Config_SessionkeyConfig;
- case: "sessionkey";
- } | {
- /**
- * @generated from field: meshtastic.DeviceUIConfig device_ui = 10;
- */
- value: DeviceUIConfig;
- case: "deviceUi";
- } | { case: undefined; value?: undefined };
+ payloadVariant:
+ | {
+ /**
+ * @generated from field: meshtastic.Config.DeviceConfig device = 1;
+ */
+ value: Config_DeviceConfig;
+ case: "device";
+ }
+ | {
+ /**
+ * @generated from field: meshtastic.Config.PositionConfig position = 2;
+ */
+ value: Config_PositionConfig;
+ case: "position";
+ }
+ | {
+ /**
+ * @generated from field: meshtastic.Config.PowerConfig power = 3;
+ */
+ value: Config_PowerConfig;
+ case: "power";
+ }
+ | {
+ /**
+ * @generated from field: meshtastic.Config.NetworkConfig network = 4;
+ */
+ value: Config_NetworkConfig;
+ case: "network";
+ }
+ | {
+ /**
+ * @generated from field: meshtastic.Config.DisplayConfig display = 5;
+ */
+ value: Config_DisplayConfig;
+ case: "display";
+ }
+ | {
+ /**
+ * @generated from field: meshtastic.Config.LoRaConfig lora = 6;
+ */
+ value: Config_LoRaConfig;
+ case: "lora";
+ }
+ | {
+ /**
+ * @generated from field: meshtastic.Config.BluetoothConfig bluetooth = 7;
+ */
+ value: Config_BluetoothConfig;
+ case: "bluetooth";
+ }
+ | {
+ /**
+ * @generated from field: meshtastic.Config.SecurityConfig security = 8;
+ */
+ value: Config_SecurityConfig;
+ case: "security";
+ }
+ | {
+ /**
+ * @generated from field: meshtastic.Config.SessionkeyConfig sessionkey = 9;
+ */
+ value: Config_SessionkeyConfig;
+ case: "sessionkey";
+ }
+ | {
+ /**
+ * @generated from field: meshtastic.DeviceUIConfig device_ui = 10;
+ */
+ value: DeviceUIConfig;
+ case: "deviceUi";
+ }
+ | { case: undefined; value?: undefined };
};
/**
* Describes the message meshtastic.Config.
* Use `create(ConfigSchema)` to create a new message.
*/
-export const ConfigSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_meshtastic_config, 0);
+export const ConfigSchema: GenMessage /*@__PURE__*/ = messageDesc(
+ file_meshtastic_config,
+ 0,
+);
/**
*
@@ -211,7 +230,7 @@ export type Config_DeviceConfig = Message<"meshtastic.Config.DeviceConfig"> & {
* Describes the message meshtastic.Config.DeviceConfig.
* Use `create(Config_DeviceConfigSchema)` to create a new message.
*/
-export const Config_DeviceConfigSchema: GenMessage = /*@__PURE__*/
+export const Config_DeviceConfigSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_config, 0, 0);
/**
@@ -361,7 +380,7 @@ export enum Config_DeviceConfig_Role {
/**
* Describes the enum meshtastic.Config.DeviceConfig.Role.
*/
-export const Config_DeviceConfig_RoleSchema: GenEnum = /*@__PURE__*/
+export const Config_DeviceConfig_RoleSchema: GenEnum /*@__PURE__*/ =
enumDesc(file_meshtastic_config, 0, 0, 0);
/**
@@ -428,7 +447,7 @@ export enum Config_DeviceConfig_RebroadcastMode {
/**
* Describes the enum meshtastic.Config.DeviceConfig.RebroadcastMode.
*/
-export const Config_DeviceConfig_RebroadcastModeSchema: GenEnum = /*@__PURE__*/
+export const Config_DeviceConfig_RebroadcastModeSchema: GenEnum /*@__PURE__*/ =
enumDesc(file_meshtastic_config, 0, 0, 1);
/**
@@ -489,7 +508,7 @@ export enum Config_DeviceConfig_BuzzerMode {
/**
* Describes the enum meshtastic.Config.DeviceConfig.BuzzerMode.
*/
-export const Config_DeviceConfig_BuzzerModeSchema: GenEnum = /*@__PURE__*/
+export const Config_DeviceConfig_BuzzerModeSchema: GenEnum /*@__PURE__*/ =
enumDesc(file_meshtastic_config, 0, 0, 2);
/**
@@ -498,125 +517,126 @@ export const Config_DeviceConfig_BuzzerModeSchema: GenEnum & {
- /**
- *
- * We should send our position this often (but only if it has changed significantly)
- * Defaults to 15 minutes
- *
- * @generated from field: uint32 position_broadcast_secs = 1;
- */
- positionBroadcastSecs: number;
+export type Config_PositionConfig =
+ Message<"meshtastic.Config.PositionConfig"> & {
+ /**
+ *
+ * We should send our position this often (but only if it has changed significantly)
+ * Defaults to 15 minutes
+ *
+ * @generated from field: uint32 position_broadcast_secs = 1;
+ */
+ positionBroadcastSecs: number;
- /**
- *
- * Adaptive position braoadcast, which is now the default.
- *
- * @generated from field: bool position_broadcast_smart_enabled = 2;
- */
- positionBroadcastSmartEnabled: boolean;
+ /**
+ *
+ * Adaptive position braoadcast, which is now the default.
+ *
+ * @generated from field: bool position_broadcast_smart_enabled = 2;
+ */
+ positionBroadcastSmartEnabled: boolean;
- /**
- *
- * If set, this node is at a fixed position.
- * We will generate GPS position updates at the regular interval, but use whatever the last lat/lon/alt we have for the node.
- * The lat/lon/alt can be set by an internal GPS or with the help of the app.
- *
- * @generated from field: bool fixed_position = 3;
- */
- fixedPosition: boolean;
+ /**
+ *
+ * If set, this node is at a fixed position.
+ * We will generate GPS position updates at the regular interval, but use whatever the last lat/lon/alt we have for the node.
+ * The lat/lon/alt can be set by an internal GPS or with the help of the app.
+ *
+ * @generated from field: bool fixed_position = 3;
+ */
+ fixedPosition: boolean;
- /**
- *
- * Is GPS enabled for this node?
- *
- * @generated from field: bool gps_enabled = 4 [deprecated = true];
- * @deprecated
- */
- gpsEnabled: boolean;
+ /**
+ *
+ * Is GPS enabled for this node?
+ *
+ * @generated from field: bool gps_enabled = 4 [deprecated = true];
+ * @deprecated
+ */
+ gpsEnabled: boolean;
- /**
- *
- * How often should we try to get GPS position (in seconds)
- * or zero for the default of once every 30 seconds
- * or a very large value (maxint) to update only once at boot.
- *
- * @generated from field: uint32 gps_update_interval = 5;
- */
- gpsUpdateInterval: number;
+ /**
+ *
+ * How often should we try to get GPS position (in seconds)
+ * or zero for the default of once every 30 seconds
+ * or a very large value (maxint) to update only once at boot.
+ *
+ * @generated from field: uint32 gps_update_interval = 5;
+ */
+ gpsUpdateInterval: number;
- /**
- *
- * Deprecated in favor of using smart / regular broadcast intervals as implicit attempt time
- *
- * @generated from field: uint32 gps_attempt_time = 6 [deprecated = true];
- * @deprecated
- */
- gpsAttemptTime: number;
+ /**
+ *
+ * Deprecated in favor of using smart / regular broadcast intervals as implicit attempt time
+ *
+ * @generated from field: uint32 gps_attempt_time = 6 [deprecated = true];
+ * @deprecated
+ */
+ gpsAttemptTime: number;
- /**
- *
- * Bit field of boolean configuration options for POSITION messages
- * (bitwise OR of PositionFlags)
- *
- * @generated from field: uint32 position_flags = 7;
- */
- positionFlags: number;
+ /**
+ *
+ * Bit field of boolean configuration options for POSITION messages
+ * (bitwise OR of PositionFlags)
+ *
+ * @generated from field: uint32 position_flags = 7;
+ */
+ positionFlags: number;
- /**
- *
- * (Re)define GPS_RX_PIN for your board.
- *
- * @generated from field: uint32 rx_gpio = 8;
- */
- rxGpio: number;
+ /**
+ *
+ * (Re)define GPS_RX_PIN for your board.
+ *
+ * @generated from field: uint32 rx_gpio = 8;
+ */
+ rxGpio: number;
- /**
- *
- * (Re)define GPS_TX_PIN for your board.
- *
- * @generated from field: uint32 tx_gpio = 9;
- */
- txGpio: number;
+ /**
+ *
+ * (Re)define GPS_TX_PIN for your board.
+ *
+ * @generated from field: uint32 tx_gpio = 9;
+ */
+ txGpio: number;
- /**
- *
- * The minimum distance in meters traveled (since the last send) before we can send a position to the mesh if position_broadcast_smart_enabled
- *
- * @generated from field: uint32 broadcast_smart_minimum_distance = 10;
- */
- broadcastSmartMinimumDistance: number;
+ /**
+ *
+ * The minimum distance in meters traveled (since the last send) before we can send a position to the mesh if position_broadcast_smart_enabled
+ *
+ * @generated from field: uint32 broadcast_smart_minimum_distance = 10;
+ */
+ broadcastSmartMinimumDistance: number;
- /**
- *
- * The minimum number of seconds (since the last send) before we can send a position to the mesh if position_broadcast_smart_enabled
- *
- * @generated from field: uint32 broadcast_smart_minimum_interval_secs = 11;
- */
- broadcastSmartMinimumIntervalSecs: number;
+ /**
+ *
+ * The minimum number of seconds (since the last send) before we can send a position to the mesh if position_broadcast_smart_enabled
+ *
+ * @generated from field: uint32 broadcast_smart_minimum_interval_secs = 11;
+ */
+ broadcastSmartMinimumIntervalSecs: number;
- /**
- *
- * (Re)define PIN_GPS_EN for your board.
- *
- * @generated from field: uint32 gps_en_gpio = 12;
- */
- gpsEnGpio: number;
+ /**
+ *
+ * (Re)define PIN_GPS_EN for your board.
+ *
+ * @generated from field: uint32 gps_en_gpio = 12;
+ */
+ gpsEnGpio: number;
- /**
- *
- * Set where GPS is enabled, disabled, or not present
- *
- * @generated from field: meshtastic.Config.PositionConfig.GpsMode gps_mode = 13;
- */
- gpsMode: Config_PositionConfig_GpsMode;
-};
+ /**
+ *
+ * Set where GPS is enabled, disabled, or not present
+ *
+ * @generated from field: meshtastic.Config.PositionConfig.GpsMode gps_mode = 13;
+ */
+ gpsMode: Config_PositionConfig_GpsMode;
+ };
/**
* Describes the message meshtastic.Config.PositionConfig.
* Use `create(Config_PositionConfigSchema)` to create a new message.
*/
-export const Config_PositionConfigSchema: GenMessage = /*@__PURE__*/
+export const Config_PositionConfigSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_config, 0, 1);
/**
@@ -727,7 +747,7 @@ export enum Config_PositionConfig_PositionFlags {
/**
* Describes the enum meshtastic.Config.PositionConfig.PositionFlags.
*/
-export const Config_PositionConfig_PositionFlagsSchema: GenEnum = /*@__PURE__*/
+export const Config_PositionConfig_PositionFlagsSchema: GenEnum /*@__PURE__*/ =
enumDesc(file_meshtastic_config, 0, 1, 0);
/**
@@ -762,7 +782,7 @@ export enum Config_PositionConfig_GpsMode {
/**
* Describes the enum meshtastic.Config.PositionConfig.GpsMode.
*/
-export const Config_PositionConfig_GpsModeSchema: GenEnum = /*@__PURE__*/
+export const Config_PositionConfig_GpsModeSchema: GenEnum /*@__PURE__*/ =
enumDesc(file_meshtastic_config, 0, 1, 1);
/**
@@ -862,7 +882,7 @@ export type Config_PowerConfig = Message<"meshtastic.Config.PowerConfig"> & {
* Describes the message meshtastic.Config.PowerConfig.
* Use `create(Config_PowerConfigSchema)` to create a new message.
*/
-export const Config_PowerConfigSchema: GenMessage = /*@__PURE__*/
+export const Config_PowerConfigSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_config, 0, 2);
/**
@@ -871,138 +891,140 @@ export const Config_PowerConfigSchema: GenMessage = /*@__PUR
*
* @generated from message meshtastic.Config.NetworkConfig
*/
-export type Config_NetworkConfig = Message<"meshtastic.Config.NetworkConfig"> & {
- /**
- *
- * Enable WiFi (disables Bluetooth)
- *
- * @generated from field: bool wifi_enabled = 1;
- */
- wifiEnabled: boolean;
+export type Config_NetworkConfig =
+ Message<"meshtastic.Config.NetworkConfig"> & {
+ /**
+ *
+ * Enable WiFi (disables Bluetooth)
+ *
+ * @generated from field: bool wifi_enabled = 1;
+ */
+ wifiEnabled: boolean;
- /**
- *
- * If set, this node will try to join the specified wifi network and
- * acquire an address via DHCP
- *
- * @generated from field: string wifi_ssid = 3;
- */
- wifiSsid: string;
+ /**
+ *
+ * If set, this node will try to join the specified wifi network and
+ * acquire an address via DHCP
+ *
+ * @generated from field: string wifi_ssid = 3;
+ */
+ wifiSsid: string;
- /**
- *
- * If set, will be use to authenticate to the named wifi
- *
- * @generated from field: string wifi_psk = 4;
- */
- wifiPsk: string;
+ /**
+ *
+ * If set, will be use to authenticate to the named wifi
+ *
+ * @generated from field: string wifi_psk = 4;
+ */
+ wifiPsk: string;
- /**
- *
- * NTP server to use if WiFi is conneced, defaults to `meshtastic.pool.ntp.org`
- *
- * @generated from field: string ntp_server = 5;
- */
- ntpServer: string;
+ /**
+ *
+ * NTP server to use if WiFi is conneced, defaults to `meshtastic.pool.ntp.org`
+ *
+ * @generated from field: string ntp_server = 5;
+ */
+ ntpServer: string;
- /**
- *
- * Enable Ethernet
- *
- * @generated from field: bool eth_enabled = 6;
- */
- ethEnabled: boolean;
+ /**
+ *
+ * Enable Ethernet
+ *
+ * @generated from field: bool eth_enabled = 6;
+ */
+ ethEnabled: boolean;
- /**
- *
- * acquire an address via DHCP or assign static
- *
- * @generated from field: meshtastic.Config.NetworkConfig.AddressMode address_mode = 7;
- */
- addressMode: Config_NetworkConfig_AddressMode;
+ /**
+ *
+ * acquire an address via DHCP or assign static
+ *
+ * @generated from field: meshtastic.Config.NetworkConfig.AddressMode address_mode = 7;
+ */
+ addressMode: Config_NetworkConfig_AddressMode;
- /**
- *
- * struct to keep static address
- *
- * @generated from field: meshtastic.Config.NetworkConfig.IpV4Config ipv4_config = 8;
- */
- ipv4Config?: Config_NetworkConfig_IpV4Config | undefined;
+ /**
+ *
+ * struct to keep static address
+ *
+ * @generated from field: meshtastic.Config.NetworkConfig.IpV4Config ipv4_config = 8;
+ */
+ ipv4Config?: Config_NetworkConfig_IpV4Config | undefined;
- /**
- *
- * rsyslog Server and Port
- *
- * @generated from field: string rsyslog_server = 9;
- */
- rsyslogServer: string;
+ /**
+ *
+ * rsyslog Server and Port
+ *
+ * @generated from field: string rsyslog_server = 9;
+ */
+ rsyslogServer: string;
- /**
- *
- * Flags for enabling/disabling network protocols
- *
- * @generated from field: uint32 enabled_protocols = 10;
- */
- enabledProtocols: number;
+ /**
+ *
+ * Flags for enabling/disabling network protocols
+ *
+ * @generated from field: uint32 enabled_protocols = 10;
+ */
+ enabledProtocols: number;
- /**
- *
- * Enable/Disable ipv6 support
- *
- * @generated from field: bool ipv6_enabled = 11;
- */
- ipv6Enabled: boolean;
-};
+ /**
+ *
+ * Enable/Disable ipv6 support
+ *
+ * @generated from field: bool ipv6_enabled = 11;
+ */
+ ipv6Enabled: boolean;
+ };
/**
* Describes the message meshtastic.Config.NetworkConfig.
* Use `create(Config_NetworkConfigSchema)` to create a new message.
*/
-export const Config_NetworkConfigSchema: GenMessage = /*@__PURE__*/
+export const Config_NetworkConfigSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_config, 0, 3);
/**
* @generated from message meshtastic.Config.NetworkConfig.IpV4Config
*/
-export type Config_NetworkConfig_IpV4Config = Message<"meshtastic.Config.NetworkConfig.IpV4Config"> & {
- /**
- *
- * Static IP address
- *
- * @generated from field: fixed32 ip = 1;
- */
- ip: number;
+export type Config_NetworkConfig_IpV4Config =
+ Message<"meshtastic.Config.NetworkConfig.IpV4Config"> & {
+ /**
+ *
+ * Static IP address
+ *
+ * @generated from field: fixed32 ip = 1;
+ */
+ ip: number;
- /**
- *
- * Static gateway address
- *
- * @generated from field: fixed32 gateway = 2;
- */
- gateway: number;
+ /**
+ *
+ * Static gateway address
+ *
+ * @generated from field: fixed32 gateway = 2;
+ */
+ gateway: number;
- /**
- *
- * Static subnet mask
- *
- * @generated from field: fixed32 subnet = 3;
- */
- subnet: number;
+ /**
+ *
+ * Static subnet mask
+ *
+ * @generated from field: fixed32 subnet = 3;
+ */
+ subnet: number;
- /**
- *
- * Static DNS server address
- *
- * @generated from field: fixed32 dns = 4;
- */
- dns: number;
-};
+ /**
+ *
+ * Static DNS server address
+ *
+ * @generated from field: fixed32 dns = 4;
+ */
+ dns: number;
+ };
/**
* Describes the message meshtastic.Config.NetworkConfig.IpV4Config.
* Use `create(Config_NetworkConfig_IpV4ConfigSchema)` to create a new message.
*/
-export const Config_NetworkConfig_IpV4ConfigSchema: GenMessage = /*@__PURE__*/
+export const Config_NetworkConfig_IpV4ConfigSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_config, 0, 3, 0);
/**
@@ -1029,7 +1051,7 @@ export enum Config_NetworkConfig_AddressMode {
/**
* Describes the enum meshtastic.Config.NetworkConfig.AddressMode.
*/
-export const Config_NetworkConfig_AddressModeSchema: GenEnum = /*@__PURE__*/
+export const Config_NetworkConfig_AddressModeSchema: GenEnum /*@__PURE__*/ =
enumDesc(file_meshtastic_config, 0, 3, 0);
/**
@@ -1059,7 +1081,7 @@ export enum Config_NetworkConfig_ProtocolFlags {
/**
* Describes the enum meshtastic.Config.NetworkConfig.ProtocolFlags.
*/
-export const Config_NetworkConfig_ProtocolFlagsSchema: GenEnum = /*@__PURE__*/
+export const Config_NetworkConfig_ProtocolFlagsSchema: GenEnum /*@__PURE__*/ =
enumDesc(file_meshtastic_config, 0, 3, 1);
/**
@@ -1068,133 +1090,134 @@ export const Config_NetworkConfig_ProtocolFlagsSchema: GenEnum & {
- /**
- *
- * Number of seconds the screen stays on after pressing the user button or receiving a message
- * 0 for default of one minute MAXUINT for always on
- *
- * @generated from field: uint32 screen_on_secs = 1;
- */
- screenOnSecs: number;
+export type Config_DisplayConfig =
+ Message<"meshtastic.Config.DisplayConfig"> & {
+ /**
+ *
+ * Number of seconds the screen stays on after pressing the user button or receiving a message
+ * 0 for default of one minute MAXUINT for always on
+ *
+ * @generated from field: uint32 screen_on_secs = 1;
+ */
+ screenOnSecs: number;
- /**
- *
- * Deprecated in 2.7.4: Unused
- * How the GPS coordinates are formatted on the OLED screen.
- *
- * @generated from field: meshtastic.Config.DisplayConfig.DeprecatedGpsCoordinateFormat gps_format = 2 [deprecated = true];
- * @deprecated
- */
- gpsFormat: Config_DisplayConfig_DeprecatedGpsCoordinateFormat;
+ /**
+ *
+ * Deprecated in 2.7.4: Unused
+ * How the GPS coordinates are formatted on the OLED screen.
+ *
+ * @generated from field: meshtastic.Config.DisplayConfig.DeprecatedGpsCoordinateFormat gps_format = 2 [deprecated = true];
+ * @deprecated
+ */
+ gpsFormat: Config_DisplayConfig_DeprecatedGpsCoordinateFormat;
- /**
- *
- * Automatically toggles to the next page on the screen like a carousel, based the specified interval in seconds.
- * Potentially useful for devices without user buttons.
- *
- * @generated from field: uint32 auto_screen_carousel_secs = 3;
- */
- autoScreenCarouselSecs: number;
+ /**
+ *
+ * Automatically toggles to the next page on the screen like a carousel, based the specified interval in seconds.
+ * Potentially useful for devices without user buttons.
+ *
+ * @generated from field: uint32 auto_screen_carousel_secs = 3;
+ */
+ autoScreenCarouselSecs: number;
- /**
- *
- * If this is set, the displayed compass will always point north. if unset, the old behaviour
- * (top of display is heading direction) is used.
- *
- * @generated from field: bool compass_north_top = 4 [deprecated = true];
- * @deprecated
- */
- compassNorthTop: boolean;
+ /**
+ *
+ * If this is set, the displayed compass will always point north. if unset, the old behaviour
+ * (top of display is heading direction) is used.
+ *
+ * @generated from field: bool compass_north_top = 4 [deprecated = true];
+ * @deprecated
+ */
+ compassNorthTop: boolean;
- /**
- *
- * Flip screen vertically, for cases that mount the screen upside down
- *
- * @generated from field: bool flip_screen = 5;
- */
- flipScreen: boolean;
+ /**
+ *
+ * Flip screen vertically, for cases that mount the screen upside down
+ *
+ * @generated from field: bool flip_screen = 5;
+ */
+ flipScreen: boolean;
- /**
- *
- * Perferred display units
- *
- * @generated from field: meshtastic.Config.DisplayConfig.DisplayUnits units = 6;
- */
- units: Config_DisplayConfig_DisplayUnits;
+ /**
+ *
+ * Perferred display units
+ *
+ * @generated from field: meshtastic.Config.DisplayConfig.DisplayUnits units = 6;
+ */
+ units: Config_DisplayConfig_DisplayUnits;
- /**
- *
- * Override auto-detect in screen
- *
- * @generated from field: meshtastic.Config.DisplayConfig.OledType oled = 7;
- */
- oled: Config_DisplayConfig_OledType;
+ /**
+ *
+ * Override auto-detect in screen
+ *
+ * @generated from field: meshtastic.Config.DisplayConfig.OledType oled = 7;
+ */
+ oled: Config_DisplayConfig_OledType;
- /**
- *
- * Display Mode
- *
- * @generated from field: meshtastic.Config.DisplayConfig.DisplayMode displaymode = 8;
- */
- displaymode: Config_DisplayConfig_DisplayMode;
+ /**
+ *
+ * Display Mode
+ *
+ * @generated from field: meshtastic.Config.DisplayConfig.DisplayMode displaymode = 8;
+ */
+ displaymode: Config_DisplayConfig_DisplayMode;
- /**
- *
- * Print first line in pseudo-bold? FALSE is original style, TRUE is bold
- *
- * @generated from field: bool heading_bold = 9;
- */
- headingBold: boolean;
+ /**
+ *
+ * Print first line in pseudo-bold? FALSE is original style, TRUE is bold
+ *
+ * @generated from field: bool heading_bold = 9;
+ */
+ headingBold: boolean;
- /**
- *
- * Should we wake the screen up on accelerometer detected motion or tap
- *
- * @generated from field: bool wake_on_tap_or_motion = 10;
- */
- wakeOnTapOrMotion: boolean;
+ /**
+ *
+ * Should we wake the screen up on accelerometer detected motion or tap
+ *
+ * @generated from field: bool wake_on_tap_or_motion = 10;
+ */
+ wakeOnTapOrMotion: boolean;
- /**
- *
- * Indicates how to rotate or invert the compass output to accurate display on the display.
- *
- * @generated from field: meshtastic.Config.DisplayConfig.CompassOrientation compass_orientation = 11;
- */
- compassOrientation: Config_DisplayConfig_CompassOrientation;
+ /**
+ *
+ * Indicates how to rotate or invert the compass output to accurate display on the display.
+ *
+ * @generated from field: meshtastic.Config.DisplayConfig.CompassOrientation compass_orientation = 11;
+ */
+ compassOrientation: Config_DisplayConfig_CompassOrientation;
- /**
- *
- * If false (default), the device will display the time in 24-hour format on screen.
- * If true, the device will display the time in 12-hour format on screen.
- *
- * @generated from field: bool use_12h_clock = 12;
- */
- use12hClock: boolean;
+ /**
+ *
+ * If false (default), the device will display the time in 24-hour format on screen.
+ * If true, the device will display the time in 12-hour format on screen.
+ *
+ * @generated from field: bool use_12h_clock = 12;
+ */
+ use12hClock: boolean;
- /**
- *
- * If false (default), the device will use short names for various display screens.
- * If true, node names will show in long format
- *
- * @generated from field: bool use_long_node_name = 13;
- */
- useLongNodeName: boolean;
+ /**
+ *
+ * If false (default), the device will use short names for various display screens.
+ * If true, node names will show in long format
+ *
+ * @generated from field: bool use_long_node_name = 13;
+ */
+ useLongNodeName: boolean;
- /**
- *
- * If true, the device will display message bubbles on screen.
- *
- * @generated from field: bool enable_message_bubbles = 14;
- */
- enableMessageBubbles: boolean;
-};
+ /**
+ *
+ * If true, the device will display message bubbles on screen.
+ *
+ * @generated from field: bool enable_message_bubbles = 14;
+ */
+ enableMessageBubbles: boolean;
+ };
/**
* Describes the message meshtastic.Config.DisplayConfig.
* Use `create(Config_DisplayConfigSchema)` to create a new message.
*/
-export const Config_DisplayConfigSchema: GenMessage = /*@__PURE__*/
+export const Config_DisplayConfigSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_config, 0, 4);
/**
@@ -1213,7 +1236,7 @@ export enum Config_DisplayConfig_DeprecatedGpsCoordinateFormat {
/**
* Describes the enum meshtastic.Config.DisplayConfig.DeprecatedGpsCoordinateFormat.
*/
-export const Config_DisplayConfig_DeprecatedGpsCoordinateFormatSchema: GenEnum = /*@__PURE__*/
+export const Config_DisplayConfig_DeprecatedGpsCoordinateFormatSchema: GenEnum /*@__PURE__*/ =
enumDesc(file_meshtastic_config, 0, 4, 0);
/**
@@ -1243,7 +1266,7 @@ export enum Config_DisplayConfig_DisplayUnits {
/**
* Describes the enum meshtastic.Config.DisplayConfig.DisplayUnits.
*/
-export const Config_DisplayConfig_DisplayUnitsSchema: GenEnum = /*@__PURE__*/
+export const Config_DisplayConfig_DisplayUnitsSchema: GenEnum /*@__PURE__*/ =
enumDesc(file_meshtastic_config, 0, 4, 1);
/**
@@ -1305,7 +1328,7 @@ export enum Config_DisplayConfig_OledType {
/**
* Describes the enum meshtastic.Config.DisplayConfig.OledType.
*/
-export const Config_DisplayConfig_OledTypeSchema: GenEnum = /*@__PURE__*/
+export const Config_DisplayConfig_OledTypeSchema: GenEnum /*@__PURE__*/ =
enumDesc(file_meshtastic_config, 0, 4, 2);
/**
@@ -1348,7 +1371,7 @@ export enum Config_DisplayConfig_DisplayMode {
/**
* Describes the enum meshtastic.Config.DisplayConfig.DisplayMode.
*/
-export const Config_DisplayConfig_DisplayModeSchema: GenEnum = /*@__PURE__*/
+export const Config_DisplayConfig_DisplayModeSchema: GenEnum /*@__PURE__*/ =
enumDesc(file_meshtastic_config, 0, 4, 3);
/**
@@ -1423,7 +1446,7 @@ export enum Config_DisplayConfig_CompassOrientation {
/**
* Describes the enum meshtastic.Config.DisplayConfig.CompassOrientation.
*/
-export const Config_DisplayConfig_CompassOrientationSchema: GenEnum = /*@__PURE__*/
+export const Config_DisplayConfig_CompassOrientationSchema: GenEnum /*@__PURE__*/ =
enumDesc(file_meshtastic_config, 0, 4, 4);
/**
@@ -1629,7 +1652,7 @@ export type Config_LoRaConfig = Message<"meshtastic.Config.LoRaConfig"> & {
* Describes the message meshtastic.Config.LoRaConfig.
* Use `create(Config_LoRaConfigSchema)` to create a new message.
*/
-export const Config_LoRaConfigSchema: GenMessage = /*@__PURE__*/
+export const Config_LoRaConfigSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_config, 0, 5);
/**
@@ -1946,7 +1969,7 @@ export enum Config_LoRaConfig_RegionCode {
/**
* Describes the enum meshtastic.Config.LoRaConfig.RegionCode.
*/
-export const Config_LoRaConfig_RegionCodeSchema: GenEnum = /*@__PURE__*/
+export const Config_LoRaConfig_RegionCodeSchema: GenEnum /*@__PURE__*/ =
enumDesc(file_meshtastic_config, 0, 5, 0);
/**
@@ -2115,7 +2138,7 @@ export enum Config_LoRaConfig_ModemPreset {
/**
* Describes the enum meshtastic.Config.LoRaConfig.ModemPreset.
*/
-export const Config_LoRaConfig_ModemPresetSchema: GenEnum = /*@__PURE__*/
+export const Config_LoRaConfig_ModemPresetSchema: GenEnum /*@__PURE__*/ =
enumDesc(file_meshtastic_config, 0, 5, 1);
/**
@@ -2150,43 +2173,44 @@ export enum Config_LoRaConfig_FEM_LNA_Mode {
/**
* Describes the enum meshtastic.Config.LoRaConfig.FEM_LNA_Mode.
*/
-export const Config_LoRaConfig_FEM_LNA_ModeSchema: GenEnum = /*@__PURE__*/
+export const Config_LoRaConfig_FEM_LNA_ModeSchema: GenEnum /*@__PURE__*/ =
enumDesc(file_meshtastic_config, 0, 5, 2);
/**
* @generated from message meshtastic.Config.BluetoothConfig
*/
-export type Config_BluetoothConfig = Message<"meshtastic.Config.BluetoothConfig"> & {
- /**
- *
- * Enable Bluetooth on the device
- *
- * @generated from field: bool enabled = 1;
- */
- enabled: boolean;
+export type Config_BluetoothConfig =
+ Message<"meshtastic.Config.BluetoothConfig"> & {
+ /**
+ *
+ * Enable Bluetooth on the device
+ *
+ * @generated from field: bool enabled = 1;
+ */
+ enabled: boolean;
- /**
- *
- * Determines the pairing strategy for the device
- *
- * @generated from field: meshtastic.Config.BluetoothConfig.PairingMode mode = 2;
- */
- mode: Config_BluetoothConfig_PairingMode;
+ /**
+ *
+ * Determines the pairing strategy for the device
+ *
+ * @generated from field: meshtastic.Config.BluetoothConfig.PairingMode mode = 2;
+ */
+ mode: Config_BluetoothConfig_PairingMode;
- /**
- *
- * Specified PIN for PairingMode.FixedPin
- *
- * @generated from field: uint32 fixed_pin = 3;
- */
- fixedPin: number;
-};
+ /**
+ *
+ * Specified PIN for PairingMode.FixedPin
+ *
+ * @generated from field: uint32 fixed_pin = 3;
+ */
+ fixedPin: number;
+ };
/**
* Describes the message meshtastic.Config.BluetoothConfig.
* Use `create(Config_BluetoothConfigSchema)` to create a new message.
*/
-export const Config_BluetoothConfigSchema: GenMessage = /*@__PURE__*/
+export const Config_BluetoothConfigSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_config, 0, 6);
/**
@@ -2221,79 +2245,80 @@ export enum Config_BluetoothConfig_PairingMode {
/**
* Describes the enum meshtastic.Config.BluetoothConfig.PairingMode.
*/
-export const Config_BluetoothConfig_PairingModeSchema: GenEnum = /*@__PURE__*/
+export const Config_BluetoothConfig_PairingModeSchema: GenEnum /*@__PURE__*/ =
enumDesc(file_meshtastic_config, 0, 6, 0);
/**
* @generated from message meshtastic.Config.SecurityConfig
*/
-export type Config_SecurityConfig = Message<"meshtastic.Config.SecurityConfig"> & {
- /**
- *
- * The public key of the user's device.
- * Sent out to other nodes on the mesh to allow them to compute a shared secret key.
- *
- * @generated from field: bytes public_key = 1;
- */
- publicKey: Uint8Array;
+export type Config_SecurityConfig =
+ Message<"meshtastic.Config.SecurityConfig"> & {
+ /**
+ *
+ * The public key of the user's device.
+ * Sent out to other nodes on the mesh to allow them to compute a shared secret key.
+ *
+ * @generated from field: bytes public_key = 1;
+ */
+ publicKey: Uint8Array;
- /**
- *
- * The private key of the device.
- * Used to create a shared key with a remote device.
- *
- * @generated from field: bytes private_key = 2;
- */
- privateKey: Uint8Array;
+ /**
+ *
+ * The private key of the device.
+ * Used to create a shared key with a remote device.
+ *
+ * @generated from field: bytes private_key = 2;
+ */
+ privateKey: Uint8Array;
- /**
- *
- * The public key authorized to send admin messages to this node.
- *
- * @generated from field: repeated bytes admin_key = 3;
- */
- adminKey: Uint8Array[];
+ /**
+ *
+ * The public key authorized to send admin messages to this node.
+ *
+ * @generated from field: repeated bytes admin_key = 3;
+ */
+ adminKey: Uint8Array[];
- /**
- *
- * If true, device is considered to be "managed" by a mesh administrator via admin messages
- * Device is managed by a mesh administrator.
- *
- * @generated from field: bool is_managed = 4;
- */
- isManaged: boolean;
+ /**
+ *
+ * If true, device is considered to be "managed" by a mesh administrator via admin messages
+ * Device is managed by a mesh administrator.
+ *
+ * @generated from field: bool is_managed = 4;
+ */
+ isManaged: boolean;
- /**
- *
- * Serial Console over the Stream API."
- *
- * @generated from field: bool serial_enabled = 5;
- */
- serialEnabled: boolean;
+ /**
+ *
+ * Serial Console over the Stream API."
+ *
+ * @generated from field: bool serial_enabled = 5;
+ */
+ serialEnabled: boolean;
- /**
- *
- * By default we turn off logging as soon as an API client connects (to keep shared serial link quiet).
- * Output live debug logging over serial or bluetooth is set to true.
- *
- * @generated from field: bool debug_log_api_enabled = 6;
- */
- debugLogApiEnabled: boolean;
+ /**
+ *
+ * By default we turn off logging as soon as an API client connects (to keep shared serial link quiet).
+ * Output live debug logging over serial or bluetooth is set to true.
+ *
+ * @generated from field: bool debug_log_api_enabled = 6;
+ */
+ debugLogApiEnabled: boolean;
- /**
- *
- * Allow incoming device control over the insecure legacy admin channel.
- *
- * @generated from field: bool admin_channel_enabled = 8;
- */
- adminChannelEnabled: boolean;
-};
+ /**
+ *
+ * Allow incoming device control over the insecure legacy admin channel.
+ *
+ * @generated from field: bool admin_channel_enabled = 8;
+ */
+ adminChannelEnabled: boolean;
+ };
/**
* Describes the message meshtastic.Config.SecurityConfig.
* Use `create(Config_SecurityConfigSchema)` to create a new message.
*/
-export const Config_SecurityConfigSchema: GenMessage = /*@__PURE__*/
+export const Config_SecurityConfigSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_config, 0, 7);
/**
@@ -2302,13 +2327,12 @@ export const Config_SecurityConfigSchema: GenMessage = /*
*
* @generated from message meshtastic.Config.SessionkeyConfig
*/
-export type Config_SessionkeyConfig = Message<"meshtastic.Config.SessionkeyConfig"> & {
-};
+export type Config_SessionkeyConfig =
+ Message<"meshtastic.Config.SessionkeyConfig"> & {};
/**
* Describes the message meshtastic.Config.SessionkeyConfig.
* Use `create(Config_SessionkeyConfigSchema)` to create a new message.
*/
-export const Config_SessionkeyConfigSchema: GenMessage = /*@__PURE__*/
+export const Config_SessionkeyConfigSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_config, 0, 8);
-
diff --git a/packages/protobufs/packages/ts/dist/meshtastic/connection_status_pb.ts b/packages/protobufs/packages/ts/dist/meshtastic/connection_status_pb.ts
index 3768ff67c..03cdf0d18 100644
--- a/packages/protobufs/packages/ts/dist/meshtastic/connection_status_pb.ts
+++ b/packages/protobufs/packages/ts/dist/meshtastic/connection_status_pb.ts
@@ -1,4 +1,4 @@
-// @generated by protoc-gen-es v2.12.0 with parameter "target=ts"
+// @generated by protoc-gen-es v2.12.1 with parameter "target=ts"
// @generated from file meshtastic/connection_status.proto (package meshtastic, syntax proto3)
/* eslint-disable */
@@ -9,51 +9,54 @@ import type { Message } from "@bufbuild/protobuf";
/**
* Describes the file meshtastic/connection_status.proto.
*/
-export const file_meshtastic_connection_status: GenFile = /*@__PURE__*/
- fileDesc("CiJtZXNodGFzdGljL2Nvbm5lY3Rpb25fc3RhdHVzLnByb3RvEgptZXNodGFzdGljIrECChZEZXZpY2VDb25uZWN0aW9uU3RhdHVzEjMKBHdpZmkYASABKAsyIC5tZXNodGFzdGljLldpZmlDb25uZWN0aW9uU3RhdHVzSACIAQESOwoIZXRoZXJuZXQYAiABKAsyJC5tZXNodGFzdGljLkV0aGVybmV0Q29ubmVjdGlvblN0YXR1c0gBiAEBEj0KCWJsdWV0b290aBgDIAEoCzIlLm1lc2h0YXN0aWMuQmx1ZXRvb3RoQ29ubmVjdGlvblN0YXR1c0gCiAEBEjcKBnNlcmlhbBgEIAEoCzIiLm1lc2h0YXN0aWMuU2VyaWFsQ29ubmVjdGlvblN0YXR1c0gDiAEBQgcKBV93aWZpQgsKCV9ldGhlcm5ldEIMCgpfYmx1ZXRvb3RoQgkKB19zZXJpYWwiZwoUV2lmaUNvbm5lY3Rpb25TdGF0dXMSMwoGc3RhdHVzGAEgASgLMiMubWVzaHRhc3RpYy5OZXR3b3JrQ29ubmVjdGlvblN0YXR1cxIMCgRzc2lkGAIgASgJEgwKBHJzc2kYAyABKAUiTwoYRXRoZXJuZXRDb25uZWN0aW9uU3RhdHVzEjMKBnN0YXR1cxgBIAEoCzIjLm1lc2h0YXN0aWMuTmV0d29ya0Nvbm5lY3Rpb25TdGF0dXMiewoXTmV0d29ya0Nvbm5lY3Rpb25TdGF0dXMSEgoKaXBfYWRkcmVzcxgBIAEoBxIUCgxpc19jb25uZWN0ZWQYAiABKAgSGQoRaXNfbXF0dF9jb25uZWN0ZWQYAyABKAgSGwoTaXNfc3lzbG9nX2Nvbm5lY3RlZBgEIAEoCCJMChlCbHVldG9vdGhDb25uZWN0aW9uU3RhdHVzEgsKA3BpbhgBIAEoDRIMCgRyc3NpGAIgASgFEhQKDGlzX2Nvbm5lY3RlZBgDIAEoCCI8ChZTZXJpYWxDb25uZWN0aW9uU3RhdHVzEgwKBGJhdWQYASABKA0SFAoMaXNfY29ubmVjdGVkGAIgASgIQmYKFG9yZy5tZXNodGFzdGljLnByb3RvQhBDb25uU3RhdHVzUHJvdG9zWiJnaXRodWIuY29tL21lc2h0YXN0aWMvZ28vZ2VuZXJhdGVkqgIUTWVzaHRhc3RpYy5Qcm90b2J1ZnO6AgBiBnByb3RvMw");
+export const file_meshtastic_connection_status: GenFile /*@__PURE__*/ =
+ fileDesc(
+ "CiJtZXNodGFzdGljL2Nvbm5lY3Rpb25fc3RhdHVzLnByb3RvEgptZXNodGFzdGljIrECChZEZXZpY2VDb25uZWN0aW9uU3RhdHVzEjMKBHdpZmkYASABKAsyIC5tZXNodGFzdGljLldpZmlDb25uZWN0aW9uU3RhdHVzSACIAQESOwoIZXRoZXJuZXQYAiABKAsyJC5tZXNodGFzdGljLkV0aGVybmV0Q29ubmVjdGlvblN0YXR1c0gBiAEBEj0KCWJsdWV0b290aBgDIAEoCzIlLm1lc2h0YXN0aWMuQmx1ZXRvb3RoQ29ubmVjdGlvblN0YXR1c0gCiAEBEjcKBnNlcmlhbBgEIAEoCzIiLm1lc2h0YXN0aWMuU2VyaWFsQ29ubmVjdGlvblN0YXR1c0gDiAEBQgcKBV93aWZpQgsKCV9ldGhlcm5ldEIMCgpfYmx1ZXRvb3RoQgkKB19zZXJpYWwiZwoUV2lmaUNvbm5lY3Rpb25TdGF0dXMSMwoGc3RhdHVzGAEgASgLMiMubWVzaHRhc3RpYy5OZXR3b3JrQ29ubmVjdGlvblN0YXR1cxIMCgRzc2lkGAIgASgJEgwKBHJzc2kYAyABKAUiTwoYRXRoZXJuZXRDb25uZWN0aW9uU3RhdHVzEjMKBnN0YXR1cxgBIAEoCzIjLm1lc2h0YXN0aWMuTmV0d29ya0Nvbm5lY3Rpb25TdGF0dXMiewoXTmV0d29ya0Nvbm5lY3Rpb25TdGF0dXMSEgoKaXBfYWRkcmVzcxgBIAEoBxIUCgxpc19jb25uZWN0ZWQYAiABKAgSGQoRaXNfbXF0dF9jb25uZWN0ZWQYAyABKAgSGwoTaXNfc3lzbG9nX2Nvbm5lY3RlZBgEIAEoCCJMChlCbHVldG9vdGhDb25uZWN0aW9uU3RhdHVzEgsKA3BpbhgBIAEoDRIMCgRyc3NpGAIgASgFEhQKDGlzX2Nvbm5lY3RlZBgDIAEoCCI8ChZTZXJpYWxDb25uZWN0aW9uU3RhdHVzEgwKBGJhdWQYASABKA0SFAoMaXNfY29ubmVjdGVkGAIgASgIQmYKFG9yZy5tZXNodGFzdGljLnByb3RvQhBDb25uU3RhdHVzUHJvdG9zWiJnaXRodWIuY29tL21lc2h0YXN0aWMvZ28vZ2VuZXJhdGVkqgIUTWVzaHRhc3RpYy5Qcm90b2J1ZnO6AgBiBnByb3RvMw",
+ );
/**
* @generated from message meshtastic.DeviceConnectionStatus
*/
-export type DeviceConnectionStatus = Message<"meshtastic.DeviceConnectionStatus"> & {
- /**
- *
- * WiFi Status
- *
- * @generated from field: optional meshtastic.WifiConnectionStatus wifi = 1;
- */
- wifi?: WifiConnectionStatus | undefined;
-
- /**
- *
- * WiFi Status
- *
- * @generated from field: optional meshtastic.EthernetConnectionStatus ethernet = 2;
- */
- ethernet?: EthernetConnectionStatus | undefined;
-
- /**
- *
- * Bluetooth Status
- *
- * @generated from field: optional meshtastic.BluetoothConnectionStatus bluetooth = 3;
- */
- bluetooth?: BluetoothConnectionStatus | undefined;
-
- /**
- *
- * Serial Status
- *
- * @generated from field: optional meshtastic.SerialConnectionStatus serial = 4;
- */
- serial?: SerialConnectionStatus | undefined;
-};
+export type DeviceConnectionStatus =
+ Message<"meshtastic.DeviceConnectionStatus"> & {
+ /**
+ *
+ * WiFi Status
+ *
+ * @generated from field: optional meshtastic.WifiConnectionStatus wifi = 1;
+ */
+ wifi?: WifiConnectionStatus | undefined;
+
+ /**
+ *
+ * WiFi Status
+ *
+ * @generated from field: optional meshtastic.EthernetConnectionStatus ethernet = 2;
+ */
+ ethernet?: EthernetConnectionStatus | undefined;
+
+ /**
+ *
+ * Bluetooth Status
+ *
+ * @generated from field: optional meshtastic.BluetoothConnectionStatus bluetooth = 3;
+ */
+ bluetooth?: BluetoothConnectionStatus | undefined;
+
+ /**
+ *
+ * Serial Status
+ *
+ * @generated from field: optional meshtastic.SerialConnectionStatus serial = 4;
+ */
+ serial?: SerialConnectionStatus | undefined;
+ };
/**
* Describes the message meshtastic.DeviceConnectionStatus.
* Use `create(DeviceConnectionStatusSchema)` to create a new message.
*/
-export const DeviceConnectionStatusSchema: GenMessage = /*@__PURE__*/
+export const DeviceConnectionStatusSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_connection_status, 0);
/**
@@ -62,37 +65,38 @@ export const DeviceConnectionStatusSchema: GenMessage =
*
* @generated from message meshtastic.WifiConnectionStatus
*/
-export type WifiConnectionStatus = Message<"meshtastic.WifiConnectionStatus"> & {
- /**
- *
- * Connection status
- *
- * @generated from field: meshtastic.NetworkConnectionStatus status = 1;
- */
- status?: NetworkConnectionStatus | undefined;
-
- /**
- *
- * WiFi access point SSID
- *
- * @generated from field: string ssid = 2;
- */
- ssid: string;
-
- /**
- *
- * RSSI of wireless connection
- *
- * @generated from field: int32 rssi = 3;
- */
- rssi: number;
-};
+export type WifiConnectionStatus =
+ Message<"meshtastic.WifiConnectionStatus"> & {
+ /**
+ *
+ * Connection status
+ *
+ * @generated from field: meshtastic.NetworkConnectionStatus status = 1;
+ */
+ status?: NetworkConnectionStatus | undefined;
+
+ /**
+ *
+ * WiFi access point SSID
+ *
+ * @generated from field: string ssid = 2;
+ */
+ ssid: string;
+
+ /**
+ *
+ * RSSI of wireless connection
+ *
+ * @generated from field: int32 rssi = 3;
+ */
+ rssi: number;
+ };
/**
* Describes the message meshtastic.WifiConnectionStatus.
* Use `create(WifiConnectionStatusSchema)` to create a new message.
*/
-export const WifiConnectionStatusSchema: GenMessage = /*@__PURE__*/
+export const WifiConnectionStatusSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_connection_status, 1);
/**
@@ -101,21 +105,22 @@ export const WifiConnectionStatusSchema: GenMessage = /*@_
*
* @generated from message meshtastic.EthernetConnectionStatus
*/
-export type EthernetConnectionStatus = Message<"meshtastic.EthernetConnectionStatus"> & {
- /**
- *
- * Connection status
- *
- * @generated from field: meshtastic.NetworkConnectionStatus status = 1;
- */
- status?: NetworkConnectionStatus | undefined;
-};
+export type EthernetConnectionStatus =
+ Message<"meshtastic.EthernetConnectionStatus"> & {
+ /**
+ *
+ * Connection status
+ *
+ * @generated from field: meshtastic.NetworkConnectionStatus status = 1;
+ */
+ status?: NetworkConnectionStatus | undefined;
+ };
/**
* Describes the message meshtastic.EthernetConnectionStatus.
* Use `create(EthernetConnectionStatusSchema)` to create a new message.
*/
-export const EthernetConnectionStatusSchema: GenMessage = /*@__PURE__*/
+export const EthernetConnectionStatusSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_connection_status, 2);
/**
@@ -124,45 +129,46 @@ export const EthernetConnectionStatusSchema: GenMessage & {
- /**
- *
- * IP address of device
- *
- * @generated from field: fixed32 ip_address = 1;
- */
- ipAddress: number;
-
- /**
- *
- * Whether the device has an active connection or not
- *
- * @generated from field: bool is_connected = 2;
- */
- isConnected: boolean;
-
- /**
- *
- * Whether the device has an active connection to an MQTT broker or not
- *
- * @generated from field: bool is_mqtt_connected = 3;
- */
- isMqttConnected: boolean;
-
- /**
- *
- * Whether the device is actively remote syslogging or not
- *
- * @generated from field: bool is_syslog_connected = 4;
- */
- isSyslogConnected: boolean;
-};
+export type NetworkConnectionStatus =
+ Message<"meshtastic.NetworkConnectionStatus"> & {
+ /**
+ *
+ * IP address of device
+ *
+ * @generated from field: fixed32 ip_address = 1;
+ */
+ ipAddress: number;
+
+ /**
+ *
+ * Whether the device has an active connection or not
+ *
+ * @generated from field: bool is_connected = 2;
+ */
+ isConnected: boolean;
+
+ /**
+ *
+ * Whether the device has an active connection to an MQTT broker or not
+ *
+ * @generated from field: bool is_mqtt_connected = 3;
+ */
+ isMqttConnected: boolean;
+
+ /**
+ *
+ * Whether the device is actively remote syslogging or not
+ *
+ * @generated from field: bool is_syslog_connected = 4;
+ */
+ isSyslogConnected: boolean;
+ };
/**
* Describes the message meshtastic.NetworkConnectionStatus.
* Use `create(NetworkConnectionStatusSchema)` to create a new message.
*/
-export const NetworkConnectionStatusSchema: GenMessage = /*@__PURE__*/
+export const NetworkConnectionStatusSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_connection_status, 3);
/**
@@ -171,37 +177,38 @@ export const NetworkConnectionStatusSchema: GenMessage
*
* @generated from message meshtastic.BluetoothConnectionStatus
*/
-export type BluetoothConnectionStatus = Message<"meshtastic.BluetoothConnectionStatus"> & {
- /**
- *
- * The pairing PIN for bluetooth
- *
- * @generated from field: uint32 pin = 1;
- */
- pin: number;
-
- /**
- *
- * RSSI of bluetooth connection
- *
- * @generated from field: int32 rssi = 2;
- */
- rssi: number;
-
- /**
- *
- * Whether the device has an active connection or not
- *
- * @generated from field: bool is_connected = 3;
- */
- isConnected: boolean;
-};
+export type BluetoothConnectionStatus =
+ Message<"meshtastic.BluetoothConnectionStatus"> & {
+ /**
+ *
+ * The pairing PIN for bluetooth
+ *
+ * @generated from field: uint32 pin = 1;
+ */
+ pin: number;
+
+ /**
+ *
+ * RSSI of bluetooth connection
+ *
+ * @generated from field: int32 rssi = 2;
+ */
+ rssi: number;
+
+ /**
+ *
+ * Whether the device has an active connection or not
+ *
+ * @generated from field: bool is_connected = 3;
+ */
+ isConnected: boolean;
+ };
/**
* Describes the message meshtastic.BluetoothConnectionStatus.
* Use `create(BluetoothConnectionStatusSchema)` to create a new message.
*/
-export const BluetoothConnectionStatusSchema: GenMessage = /*@__PURE__*/
+export const BluetoothConnectionStatusSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_connection_status, 4);
/**
@@ -210,28 +217,28 @@ export const BluetoothConnectionStatusSchema: GenMessage & {
- /**
- *
- * Serial baud rate
- *
- * @generated from field: uint32 baud = 1;
- */
- baud: number;
-
- /**
- *
- * Whether the device has an active connection or not
- *
- * @generated from field: bool is_connected = 2;
- */
- isConnected: boolean;
-};
+export type SerialConnectionStatus =
+ Message<"meshtastic.SerialConnectionStatus"> & {
+ /**
+ *
+ * Serial baud rate
+ *
+ * @generated from field: uint32 baud = 1;
+ */
+ baud: number;
+
+ /**
+ *
+ * Whether the device has an active connection or not
+ *
+ * @generated from field: bool is_connected = 2;
+ */
+ isConnected: boolean;
+ };
/**
* Describes the message meshtastic.SerialConnectionStatus.
* Use `create(SerialConnectionStatusSchema)` to create a new message.
*/
-export const SerialConnectionStatusSchema: GenMessage = /*@__PURE__*/
+export const SerialConnectionStatusSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_connection_status, 5);
-
diff --git a/packages/protobufs/packages/ts/dist/meshtastic/device_ui_pb.ts b/packages/protobufs/packages/ts/dist/meshtastic/device_ui_pb.ts
index 20fe43447..22e8d692d 100644
--- a/packages/protobufs/packages/ts/dist/meshtastic/device_ui_pb.ts
+++ b/packages/protobufs/packages/ts/dist/meshtastic/device_ui_pb.ts
@@ -1,16 +1,21 @@
-// @generated by protoc-gen-es v2.12.0 with parameter "target=ts"
+// @generated by protoc-gen-es v2.12.1 with parameter "target=ts"
// @generated from file meshtastic/device_ui.proto (package meshtastic, syntax proto3)
/* eslint-disable */
-import type { GenEnum, GenFile, GenMessage } from "@bufbuild/protobuf/codegenv2";
+import type {
+ GenEnum,
+ GenFile,
+ GenMessage,
+} from "@bufbuild/protobuf/codegenv2";
import { enumDesc, fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2";
import type { Message } from "@bufbuild/protobuf";
/**
* Describes the file meshtastic/device_ui.proto.
*/
-export const file_meshtastic_device_ui: GenFile = /*@__PURE__*/
- fileDesc("ChptZXNodGFzdGljL2RldmljZV91aS5wcm90bxIKbWVzaHRhc3RpYyLABQoORGV2aWNlVUlDb25maWcSDwoHdmVyc2lvbhgBIAEoDRIZChFzY3JlZW5fYnJpZ2h0bmVzcxgCIAEoDRIWCg5zY3JlZW5fdGltZW91dBgDIAEoDRITCgtzY3JlZW5fbG9jaxgEIAEoCBIVCg1zZXR0aW5nc19sb2NrGAUgASgIEhAKCHBpbl9jb2RlGAYgASgNEiAKBXRoZW1lGAcgASgOMhEubWVzaHRhc3RpYy5UaGVtZRIVCg1hbGVydF9lbmFibGVkGAggASgIEhYKDmJhbm5lcl9lbmFibGVkGAkgASgIEhQKDHJpbmdfdG9uZV9pZBgKIAEoDRImCghsYW5ndWFnZRgLIAEoDjIULm1lc2h0YXN0aWMuTGFuZ3VhZ2USKwoLbm9kZV9maWx0ZXIYDCABKAsyFi5tZXNodGFzdGljLk5vZGVGaWx0ZXISMQoObm9kZV9oaWdobGlnaHQYDSABKAsyGS5tZXNodGFzdGljLk5vZGVIaWdobGlnaHQSGAoQY2FsaWJyYXRpb25fZGF0YRgOIAEoDBIhCghtYXBfZGF0YRgPIAEoCzIPLm1lc2h0YXN0aWMuTWFwEi0KDGNvbXBhc3NfbW9kZRgQIAEoDjIXLm1lc2h0YXN0aWMuQ29tcGFzc01vZGUSGAoQc2NyZWVuX3JnYl9jb2xvchgRIAEoDRIbChNpc19jbG9ja2ZhY2VfYW5hbG9nGBIgASgIEkIKCmdwc19mb3JtYXQYEyABKA4yLi5tZXNodGFzdGljLkRldmljZVVJQ29uZmlnLkdwc0Nvb3JkaW5hdGVGb3JtYXQiVgoTR3BzQ29vcmRpbmF0ZUZvcm1hdBIHCgNERUMQABIHCgNETVMQARIHCgNVVE0QAhIICgRNR1JTEAMSBwoDT0xDEAQSCAoET1NHUhAFEgcKA01MUxAGIqcBCgpOb2RlRmlsdGVyEhYKDnVua25vd25fc3dpdGNoGAEgASgIEhYKDm9mZmxpbmVfc3dpdGNoGAIgASgIEhkKEXB1YmxpY19rZXlfc3dpdGNoGAMgASgIEhEKCWhvcHNfYXdheRgEIAEoBRIXCg9wb3NpdGlvbl9zd2l0Y2gYBSABKAgSEQoJbm9kZV9uYW1lGAYgASgJEg8KB2NoYW5uZWwYByABKAUifgoNTm9kZUhpZ2hsaWdodBITCgtjaGF0X3N3aXRjaBgBIAEoCBIXCg9wb3NpdGlvbl9zd2l0Y2gYAiABKAgSGAoQdGVsZW1ldHJ5X3N3aXRjaBgDIAEoCBISCgppYXFfc3dpdGNoGAQgASgIEhEKCW5vZGVfbmFtZRgFIAEoCSI9CghHZW9Qb2ludBIMCgR6b29tGAEgASgFEhAKCGxhdGl0dWRlGAIgASgFEhEKCWxvbmdpdHVkZRgDIAEoBSJMCgNNYXASIgoEaG9tZRgBIAEoCzIULm1lc2h0YXN0aWMuR2VvUG9pbnQSDQoFc3R5bGUYAiABKAkSEgoKZm9sbG93X2dwcxgDIAEoCCo+CgtDb21wYXNzTW9kZRILCgdEWU5BTUlDEAASDgoKRklYRURfUklORxABEhIKDkZSRUVaRV9IRUFESU5HEAIqJQoFVGhlbWUSCAoEREFSSxAAEgkKBUxJR0hUEAESBwoDUkVEEAIqwAIKCExhbmd1YWdlEgsKB0VOR0xJU0gQABIKCgZGUkVOQ0gQARIKCgZHRVJNQU4QAhILCgdJVEFMSUFOEAMSDgoKUE9SVFVHVUVTRRAEEgsKB1NQQU5JU0gQBRILCgdTV0VESVNIEAYSCwoHRklOTklTSBAHEgoKBlBPTElTSBAIEgsKB1RVUktJU0gQCRILCgdTRVJCSUFOEAoSCwoHUlVTU0lBThALEgkKBURVVENIEAwSCQoFR1JFRUsQDRINCglOT1JXRUdJQU4QDhINCglTTE9WRU5JQU4QDxINCglVS1JBSU5JQU4QEBINCglCVUxHQVJJQU4QERIJCgVDWkVDSBASEgoKBkRBTklTSBATEhYKElNJTVBMSUZJRURfQ0hJTkVTRRAeEhcKE1RSQURJVElPTkFMX0NISU5FU0UQH0JkChRvcmcubWVzaHRhc3RpYy5wcm90b0IORGV2aWNlVUlQcm90b3NaImdpdGh1Yi5jb20vbWVzaHRhc3RpYy9nby9nZW5lcmF0ZWSqAhRNZXNodGFzdGljLlByb3RvYnVmc7oCAGIGcHJvdG8z");
+export const file_meshtastic_device_ui: GenFile /*@__PURE__*/ = fileDesc(
+ "ChptZXNodGFzdGljL2RldmljZV91aS5wcm90bxIKbWVzaHRhc3RpYyLABQoORGV2aWNlVUlDb25maWcSDwoHdmVyc2lvbhgBIAEoDRIZChFzY3JlZW5fYnJpZ2h0bmVzcxgCIAEoDRIWCg5zY3JlZW5fdGltZW91dBgDIAEoDRITCgtzY3JlZW5fbG9jaxgEIAEoCBIVCg1zZXR0aW5nc19sb2NrGAUgASgIEhAKCHBpbl9jb2RlGAYgASgNEiAKBXRoZW1lGAcgASgOMhEubWVzaHRhc3RpYy5UaGVtZRIVCg1hbGVydF9lbmFibGVkGAggASgIEhYKDmJhbm5lcl9lbmFibGVkGAkgASgIEhQKDHJpbmdfdG9uZV9pZBgKIAEoDRImCghsYW5ndWFnZRgLIAEoDjIULm1lc2h0YXN0aWMuTGFuZ3VhZ2USKwoLbm9kZV9maWx0ZXIYDCABKAsyFi5tZXNodGFzdGljLk5vZGVGaWx0ZXISMQoObm9kZV9oaWdobGlnaHQYDSABKAsyGS5tZXNodGFzdGljLk5vZGVIaWdobGlnaHQSGAoQY2FsaWJyYXRpb25fZGF0YRgOIAEoDBIhCghtYXBfZGF0YRgPIAEoCzIPLm1lc2h0YXN0aWMuTWFwEi0KDGNvbXBhc3NfbW9kZRgQIAEoDjIXLm1lc2h0YXN0aWMuQ29tcGFzc01vZGUSGAoQc2NyZWVuX3JnYl9jb2xvchgRIAEoDRIbChNpc19jbG9ja2ZhY2VfYW5hbG9nGBIgASgIEkIKCmdwc19mb3JtYXQYEyABKA4yLi5tZXNodGFzdGljLkRldmljZVVJQ29uZmlnLkdwc0Nvb3JkaW5hdGVGb3JtYXQiVgoTR3BzQ29vcmRpbmF0ZUZvcm1hdBIHCgNERUMQABIHCgNETVMQARIHCgNVVE0QAhIICgRNR1JTEAMSBwoDT0xDEAQSCAoET1NHUhAFEgcKA01MUxAGIqcBCgpOb2RlRmlsdGVyEhYKDnVua25vd25fc3dpdGNoGAEgASgIEhYKDm9mZmxpbmVfc3dpdGNoGAIgASgIEhkKEXB1YmxpY19rZXlfc3dpdGNoGAMgASgIEhEKCWhvcHNfYXdheRgEIAEoBRIXCg9wb3NpdGlvbl9zd2l0Y2gYBSABKAgSEQoJbm9kZV9uYW1lGAYgASgJEg8KB2NoYW5uZWwYByABKAUifgoNTm9kZUhpZ2hsaWdodBITCgtjaGF0X3N3aXRjaBgBIAEoCBIXCg9wb3NpdGlvbl9zd2l0Y2gYAiABKAgSGAoQdGVsZW1ldHJ5X3N3aXRjaBgDIAEoCBISCgppYXFfc3dpdGNoGAQgASgIEhEKCW5vZGVfbmFtZRgFIAEoCSI9CghHZW9Qb2ludBIMCgR6b29tGAEgASgFEhAKCGxhdGl0dWRlGAIgASgFEhEKCWxvbmdpdHVkZRgDIAEoBSJMCgNNYXASIgoEaG9tZRgBIAEoCzIULm1lc2h0YXN0aWMuR2VvUG9pbnQSDQoFc3R5bGUYAiABKAkSEgoKZm9sbG93X2dwcxgDIAEoCCo+CgtDb21wYXNzTW9kZRILCgdEWU5BTUlDEAASDgoKRklYRURfUklORxABEhIKDkZSRUVaRV9IRUFESU5HEAIqJQoFVGhlbWUSCAoEREFSSxAAEgkKBUxJR0hUEAESBwoDUkVEEAIqwAIKCExhbmd1YWdlEgsKB0VOR0xJU0gQABIKCgZGUkVOQ0gQARIKCgZHRVJNQU4QAhILCgdJVEFMSUFOEAMSDgoKUE9SVFVHVUVTRRAEEgsKB1NQQU5JU0gQBRILCgdTV0VESVNIEAYSCwoHRklOTklTSBAHEgoKBlBPTElTSBAIEgsKB1RVUktJU0gQCRILCgdTRVJCSUFOEAoSCwoHUlVTU0lBThALEgkKBURVVENIEAwSCQoFR1JFRUsQDRINCglOT1JXRUdJQU4QDhINCglTTE9WRU5JQU4QDxINCglVS1JBSU5JQU4QEBINCglCVUxHQVJJQU4QERIJCgVDWkVDSBASEgoKBkRBTklTSBATEhYKElNJTVBMSUZJRURfQ0hJTkVTRRAeEhcKE1RSQURJVElPTkFMX0NISU5FU0UQH0JkChRvcmcubWVzaHRhc3RpYy5wcm90b0IORGV2aWNlVUlQcm90b3NaImdpdGh1Yi5jb20vbWVzaHRhc3RpYy9nby9nZW5lcmF0ZWSqAhRNZXNodGFzdGljLlByb3RvYnVmc7oCAGIGcHJvdG8z",
+);
/**
* @generated from message meshtastic.DeviceUIConfig
@@ -163,7 +168,7 @@ export type DeviceUIConfig = Message<"meshtastic.DeviceUIConfig"> & {
* Describes the message meshtastic.DeviceUIConfig.
* Use `create(DeviceUIConfigSchema)` to create a new message.
*/
-export const DeviceUIConfigSchema: GenMessage = /*@__PURE__*/
+export const DeviceUIConfigSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_device_ui, 0);
/**
@@ -241,7 +246,7 @@ export enum DeviceUIConfig_GpsCoordinateFormat {
/**
* Describes the enum meshtastic.DeviceUIConfig.GpsCoordinateFormat.
*/
-export const DeviceUIConfig_GpsCoordinateFormatSchema: GenEnum = /*@__PURE__*/
+export const DeviceUIConfig_GpsCoordinateFormatSchema: GenEnum /*@__PURE__*/ =
enumDesc(file_meshtastic_device_ui, 0, 0);
/**
@@ -309,7 +314,7 @@ export type NodeFilter = Message<"meshtastic.NodeFilter"> & {
* Describes the message meshtastic.NodeFilter.
* Use `create(NodeFilterSchema)` to create a new message.
*/
-export const NodeFilterSchema: GenMessage = /*@__PURE__*/
+export const NodeFilterSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_device_ui, 1);
/**
@@ -361,7 +366,7 @@ export type NodeHighlight = Message<"meshtastic.NodeHighlight"> & {
* Describes the message meshtastic.NodeHighlight.
* Use `create(NodeHighlightSchema)` to create a new message.
*/
-export const NodeHighlightSchema: GenMessage = /*@__PURE__*/
+export const NodeHighlightSchema: GenMessage /*@__PURE__*/ =
messageDesc(file_meshtastic_device_ui, 2);
/**
@@ -397,8 +402,10 @@ export type GeoPoint = Message<"meshtastic.GeoPoint"> & {
* Describes the message meshtastic.GeoPoint.
* Use `create(GeoPointSchema)` to create a new message.
*/
-export const GeoPointSchema: GenMessage = /*@__PURE__*/
- messageDesc(file_meshtastic_device_ui, 3);
+export const GeoPointSchema: GenMessage /*@__PURE__*/ = messageDesc(
+ file_meshtastic_device_ui,
+ 3,
+);
/**
* @generated from message meshtastic.Map
@@ -433,8 +440,10 @@ export type Map = Message<"meshtastic.Map"> & {
* Describes the message meshtastic.Map.
* Use `create(MapSchema)` to create a new message.
*/
-export const MapSchema: GenMessage