@@ -341,7 +362,7 @@ const App = ({
// Prevent flash of app UI before redirecting to onboarding
// If user needs onboarding and is NOT on an onboarding route, show loading
- if (!isOnboarded && !isPasswordSet && !isOnboardingRoute) {
+ if (!isFleetHosted && !isOnboarded && !isPasswordSet && !isOnboardingRoute) {
return (
@@ -353,7 +374,7 @@ const App = ({
// not already on a password-change route. Without this, page-level hooks
// that aren't threaded through canAccessProtectedApi (useTelemetry etc.)
// would mount and fire a 403 burst before the redirect effect navigates.
- if (isDefaultPasswordActive && !isPasswordChangeRoute) {
+ if (!isFleetHosted && isDefaultPasswordActive && !isPasswordChangeRoute) {
return
;
}
@@ -362,7 +383,7 @@ const App = ({
// route hooks (useTelemetry, useTimeSeries, etc.) fire 401/403 bursts before
// LoginModal or the default-password redirect takes over. LoginModal itself
// still renders below so the user can recover from an expired session.
- const gateRouteChildren = isAuthRequiredPath(pathname) && !canAccessProtectedApi;
+ const gateRouteChildren = !isFleetHosted && isAuthRequiredPath(pathname) && !canAccessProtectedApi;
// ============================================================================
// RENDER
@@ -377,7 +398,9 @@ const App = ({
{/* Login Modal - Layout agnostic */}
- {showLoginModal ?
: null}
+ {!isFleetHosted && showLoginModal ? (
+
+ ) : null}
{/* Wake Dialog - Layout agnostic */}
diff --git a/client/src/protoOS/components/AppLayout/AppLayout.test.tsx b/client/src/protoOS/components/AppLayout/AppLayout.test.tsx
new file mode 100644
index 000000000..bf3327914
--- /dev/null
+++ b/client/src/protoOS/components/AppLayout/AppLayout.test.tsx
@@ -0,0 +1,48 @@
+import { MemoryRouter } from "react-router-dom";
+import { render, screen, within } from "@testing-library/react";
+import { beforeEach, describe, expect, it } from "vitest";
+
+import AppLayout from "./AppLayout";
+import { navigationMenuTypes } from "@/protoOS/components/NavigationMenu";
+import { MinerHostingProvider } from "@/protoOS/contexts/MinerHostingContext";
+import useMinerStore from "@/protoOS/store/useMinerStore";
+
+describe("AppLayout", () => {
+ beforeEach(() => {
+ useMinerStore.getState().systemInfo.setSystemInfo({
+ product_name: "Proto Rig",
+ os: { version: "1.8.0" },
+ });
+ useMinerStore.getState().networkInfo.setNetworkInfo({
+ ip: "192.168.2.14",
+ mac: "02:00:00:07:3A:11",
+ });
+ });
+
+ it("uses host metadata for the navigation info panel in fleet-hosted mode", () => {
+ render(
+
+
+ }>
+ Content
+
+
+ ,
+ );
+
+ expect(within(screen.getByTestId("miner-name-info-item")).getByText("Antminer S21")).toBeInTheDocument();
+ expect(within(screen.getByTestId("ip-address-info-item")).getByText("10.0.0.42")).toBeInTheDocument();
+ expect(within(screen.getByTestId("version-info-item")).getByText("2026.1")).toBeInTheDocument();
+ expect(within(screen.getByTestId("mac-address-info-item")).getByText("AA:BB:CC:DD:EE:FF")).toBeInTheDocument();
+
+ expect(within(screen.getByTestId("miner-name-info-item")).queryByText("Proto Rig")).not.toBeInTheDocument();
+ });
+});
diff --git a/client/src/protoOS/components/AppLayout/AppLayout.tsx b/client/src/protoOS/components/AppLayout/AppLayout.tsx
index 3b307d438..9f5050775 100644
--- a/client/src/protoOS/components/AppLayout/AppLayout.tsx
+++ b/client/src/protoOS/components/AppLayout/AppLayout.tsx
@@ -6,6 +6,7 @@ import { ContentLayoutProps } from "@/protoOS/components/ContentLayout/types";
import NavigationMenu, { NavigationMenuType } from "@/protoOS/components/NavigationMenu";
import PageHeader from "@/protoOS/components/PageHeader";
+import { useMinerHosting } from "@/protoOS/contexts/MinerHostingContext";
import {
useIpAddress,
useMacAddress,
@@ -32,6 +33,8 @@ const AppLayout = ({
ContentLayout = DefaultContentLayout,
}: AppLayoutProps) => {
const [isMenuOpen, setIsMenuOpen] = useState(false);
+ const { metadata = {}, mode } = useMinerHosting();
+ const isFleetHosted = mode === "fleet";
// Read system info from store
const osVersion = useOSVersion();
@@ -48,22 +51,22 @@ const AppLayout = ({
setIsMenuOpen(false)}
versionInfo={{
- value: osVersion,
- loading: pendingSystemInfo,
+ value: isFleetHosted ? metadata.firmwareVersion : osVersion,
+ loading: isFleetHosted ? false : pendingSystemInfo,
}}
ipAddressInfo={{
- value: ipAddress,
- loading: pendingNetworkInfo,
+ value: isFleetHosted ? metadata.ipAddress : ipAddress,
+ loading: isFleetHosted ? false : pendingNetworkInfo,
}}
minerNameInfo={{
- value: productName,
- loading: pendingSystemInfo,
+ value: isFleetHosted ? metadata.minerName : productName,
+ loading: isFleetHosted ? false : pendingSystemInfo,
}}
type={type}
/>
diff --git a/client/src/protoOS/components/PageHeader/GlobalActions/GlobalActionsWidget.test.tsx b/client/src/protoOS/components/PageHeader/GlobalActions/GlobalActionsWidget.test.tsx
index 495edee53..596751ede 100644
--- a/client/src/protoOS/components/PageHeader/GlobalActions/GlobalActionsWidget.test.tsx
+++ b/client/src/protoOS/components/PageHeader/GlobalActions/GlobalActionsWidget.test.tsx
@@ -17,7 +17,7 @@ describe("GlobalActionsWidget", () => {
});
test("renders ellipsis button", () => {
- const { container } = render(
+ const { container, getByLabelText, getByTestId } = render(
,
@@ -25,6 +25,9 @@ describe("GlobalActionsWidget", () => {
const button = container.querySelector("button");
expect(button).toBeInTheDocument();
+ expect(getByLabelText("Global actions")).toBeInTheDocument();
+ expect(getByTestId("global-actions-widget")).toHaveClass("!h-8", "!w-8", "!p-0");
+ expect(getByTestId("global-actions-widget").querySelector("svg")?.parentElement).toHaveClass("h-4", "shrink-0");
});
test("opens popover when ellipsis button is clicked", () => {
diff --git a/client/src/protoOS/components/PageHeader/GlobalActions/GlobalActionsWidget.tsx b/client/src/protoOS/components/PageHeader/GlobalActions/GlobalActionsWidget.tsx
index 1eb209e93..2f497760b 100644
--- a/client/src/protoOS/components/PageHeader/GlobalActions/GlobalActionsWidget.tsx
+++ b/client/src/protoOS/components/PageHeader/GlobalActions/GlobalActionsWidget.tsx
@@ -35,14 +35,14 @@ export const GlobalActionsWidget = ({ onBlinkLEDs, onDownloadLogs }: GlobalActio
setIsOpen((prev) => !prev)}
- className="w-[28px] p-0 text-text-primary"
+ className="!h-8 !w-8 !p-0 text-text-primary"
isOpen={isOpen}
testId="global-actions-widget"
ariaLabel="Global actions"
ariaHasPopup="menu"
ariaExpanded={isOpen}
>
-
+
{isOpen ? : null}
diff --git a/client/src/protoOS/components/PageHeader/GlobalActions/GlobalActionsWidgetWrapper.test.tsx b/client/src/protoOS/components/PageHeader/GlobalActions/GlobalActionsWidgetWrapper.test.tsx
index 2a54b9ecf..e2e98df0b 100644
--- a/client/src/protoOS/components/PageHeader/GlobalActions/GlobalActionsWidgetWrapper.test.tsx
+++ b/client/src/protoOS/components/PageHeader/GlobalActions/GlobalActionsWidgetWrapper.test.tsx
@@ -3,6 +3,7 @@ import { beforeEach, describe, expect, type Mock, test, vi } from "vitest";
import GlobalActionsWidgetWrapper from "./GlobalActionsWidgetWrapper";
import { useDownloadLogs } from "@/protoOS/api/hooks/useDownloadLogs";
import { useLocateSystem } from "@/protoOS/api/hooks/useLocateSystem";
+import { useMinerHosting } from "@/protoOS/contexts/MinerHostingContext";
import { AUTH_ACTIONS } from "@/protoOS/store/types";
const { mockCheckAccess, mockSetPausedAuthAction, mockSetDismissedLoginModal, mockState } = vi.hoisted(() => ({
@@ -24,6 +25,10 @@ vi.mock("@/protoOS/api/hooks/useDownloadLogs", () => ({
useDownloadLogs: vi.fn(),
}));
+vi.mock("@/protoOS/contexts/MinerHostingContext", () => ({
+ useMinerHosting: vi.fn(),
+}));
+
vi.mock("@/protoOS/store", async () => {
const { AUTH_ACTIONS: actions } = await import("@/protoOS/store/types");
return {
@@ -49,6 +54,8 @@ describe("GlobalActionsWidgetWrapper", () => {
mockState.pausedAuthAction = null;
mockState.dismissedLoginModal = false;
+ (useMinerHosting as Mock).mockReturnValue({ mode: "direct" });
+
(useLocateSystem as Mock).mockReturnValue({
locateSystem: mockLocateSystem,
pending: false,
@@ -81,6 +88,25 @@ describe("GlobalActionsWidgetWrapper", () => {
expect(mockLocateSystem).not.toHaveBeenCalled();
});
+ test("calls locateSystem directly when Blink LEDs is clicked in fleet-hosted mode", () => {
+ (useMinerHosting as Mock).mockReturnValue({ mode: "fleet" });
+
+ const { container, getByText } = render();
+
+ const ellipsisButton = container.querySelector("button");
+ fireEvent.click(ellipsisButton!);
+
+ const blinkButton = getByText("Blink LEDs").closest("button");
+ fireEvent.click(blinkButton!);
+
+ expect(mockSetPausedAuthAction).not.toHaveBeenCalledWith(AUTH_ACTIONS.locate);
+ expect(mockCheckAccess).not.toHaveBeenCalled();
+ expect(mockLocateSystem).toHaveBeenCalledWith({
+ ledOnTime: 30,
+ onError: expect.any(Function),
+ });
+ });
+
test("calls locateSystem after auth succeeds", () => {
mockState.hasAccess = true;
mockState.pausedAuthAction = AUTH_ACTIONS.locate;
diff --git a/client/src/protoOS/components/PageHeader/GlobalActions/GlobalActionsWidgetWrapper.tsx b/client/src/protoOS/components/PageHeader/GlobalActions/GlobalActionsWidgetWrapper.tsx
index 4a3f54381..d12075b9f 100644
--- a/client/src/protoOS/components/PageHeader/GlobalActions/GlobalActionsWidgetWrapper.tsx
+++ b/client/src/protoOS/components/PageHeader/GlobalActions/GlobalActionsWidgetWrapper.tsx
@@ -3,6 +3,7 @@ import { GlobalActionsWidget } from "./GlobalActionsWidget";
import type { ErrorProps } from "@/protoOS/api/apiResponseTypes";
import { useDownloadLogs } from "@/protoOS/api/hooks/useDownloadLogs";
import { useLocateSystem } from "@/protoOS/api/hooks/useLocateSystem";
+import { useMinerHosting } from "@/protoOS/contexts/MinerHostingContext";
import {
AUTH_ACTIONS,
useAccessToken,
@@ -20,13 +21,17 @@ const GlobalActionsWidgetWrapper = () => {
const { locateSystem } = useLocateSystem();
const { downloadLogs } = useDownloadLogs();
const [error, setError] = useState(null);
+ const { mode } = useMinerHosting();
+ const isFleetHosted = mode === "fleet";
const dismissedLoginModal = useDismissedLoginModal();
const setDismissedLoginModal = useSetDismissedLoginModal();
const pausedAuthAction = usePausedAuthAction();
const setPausedAuthAction = useSetPausedAuthAction();
- const { checkAccess, hasAccess } = useAccessToken(pausedAuthAction === AUTH_ACTIONS.locate && !dismissedLoginModal);
+ const { checkAccess, hasAccess } = useAccessToken(
+ !isFleetHosted && pausedAuthAction === AUTH_ACTIONS.locate && !dismissedLoginModal,
+ );
// After successful login, retry the locate request
useEffect(() => {
@@ -48,6 +53,14 @@ const GlobalActionsWidgetWrapper = () => {
}, [dismissedLoginModal, setDismissedLoginModal, setPausedAuthAction]);
const handleBlinkLEDs = () => {
+ if (isFleetHosted) {
+ locateSystem({
+ ledOnTime: 30,
+ onError: (err) => setError(err),
+ });
+ return;
+ }
+
setPausedAuthAction(AUTH_ACTIONS.locate);
checkAccess();
};
diff --git a/client/src/protoOS/components/PageHeader/PageHeader.test.tsx b/client/src/protoOS/components/PageHeader/PageHeader.test.tsx
new file mode 100644
index 000000000..aa61f38d3
--- /dev/null
+++ b/client/src/protoOS/components/PageHeader/PageHeader.test.tsx
@@ -0,0 +1,55 @@
+import { render, screen } from "@testing-library/react";
+import { beforeEach, describe, expect, test, vi } from "vitest";
+import PageHeader from "./PageHeader";
+import { useWindowDimensions } from "@/shared/hooks/useWindowDimensions";
+
+vi.mock("@/shared/hooks/useWindowDimensions", () => ({
+ useWindowDimensions: vi.fn(),
+}));
+
+vi.mock("./GlobalActions", () => ({
+ default: () => ,
+}));
+
+vi.mock("./MinerStatus", () => ({
+ default: () => ,
+}));
+
+vi.mock("./PoolStatus", () => ({
+ default: () => ,
+}));
+
+vi.mock("./Power", () => ({
+ default: () => ,
+}));
+
+vi.mock("./PowerTarget", () => ({
+ default: () => ,
+}));
+
+vi.mock("@/protoOS/features/firmwareUpdate/components/FirmwareUpdateStatus", () => ({
+ default: () => ,
+}));
+
+describe("PageHeader", () => {
+ beforeEach(() => {
+ vi.clearAllMocks();
+ vi.mocked(useWindowDimensions).mockReturnValue({
+ isDesktop: true,
+ isLaptop: false,
+ isPhone: false,
+ isTablet: false,
+ width: 1440,
+ height: 900,
+ });
+ });
+
+ test("renders miner action widgets", () => {
+ render();
+
+ expect(screen.getByTestId("power-target")).toBeInTheDocument();
+ expect(screen.getByTestId("pool-status")).toBeInTheDocument();
+ expect(screen.getByTestId("power-widget")).toBeInTheDocument();
+ expect(screen.getByTestId("global-actions")).toBeInTheDocument();
+ });
+});
diff --git a/client/src/protoOS/components/PageHeader/Power/PowerWidget.test.tsx b/client/src/protoOS/components/PageHeader/Power/PowerWidget.test.tsx
index 20e559322..dafcb5a5a 100644
--- a/client/src/protoOS/components/PageHeader/Power/PowerWidget.test.tsx
+++ b/client/src/protoOS/components/PageHeader/Power/PowerWidget.test.tsx
@@ -2,15 +2,38 @@ import { BrowserRouter } from "react-router-dom";
import { fireEvent, render } from "@testing-library/react";
import { beforeEach, describe, expect, type Mock, test, vi } from "vitest";
import PowerWidget from "./PowerWidget";
+import { useMinerHosting } from "@/protoOS/contexts/MinerHostingContext";
import { useIsAwake, useIsSleeping } from "@/protoOS/store";
import { PopoverProvider } from "@/shared/components/Popover";
+const { mockCheckAccess, mockSetHasAccess, mockSetDismissedLoginModal, mockSetPausedAuthAction, mockState } =
+ vi.hoisted(() => ({
+ mockCheckAccess: vi.fn(),
+ mockSetHasAccess: vi.fn(),
+ mockSetDismissedLoginModal: vi.fn(),
+ mockSetPausedAuthAction: vi.fn(),
+ mockState: {
+ dismissedLoginModal: false,
+ hasAccess: undefined as boolean | undefined,
+ pausedAuthAction: null as string | null,
+ },
+ }));
+
vi.mock("@/protoOS/store", async (importOriginal) => {
const actual = (await importOriginal()) as any;
return {
...actual,
useIsAwake: vi.fn(() => true),
useIsSleeping: vi.fn(() => false),
+ useAccessToken: vi.fn(() => ({
+ checkAccess: mockCheckAccess,
+ hasAccess: mockState.hasAccess,
+ setHasAccess: mockSetHasAccess,
+ })),
+ useDismissedLoginModal: vi.fn(() => mockState.dismissedLoginModal),
+ useSetDismissedLoginModal: vi.fn(() => mockSetDismissedLoginModal),
+ usePausedAuthAction: vi.fn(() => mockState.pausedAuthAction),
+ useSetPausedAuthAction: vi.fn(() => mockSetPausedAuthAction),
};
});
@@ -32,6 +55,10 @@ vi.mock("@/protoOS/features/auth/contexts/AuthContext", () => ({
})),
}));
+vi.mock("@/protoOS/contexts/MinerHostingContext", () => ({
+ useMinerHosting: vi.fn(),
+}));
+
describe("Power Widget", () => {
const powerButton = "power-button";
const powerPopover = "power-popover";
@@ -47,10 +74,28 @@ describe("Power Widget", () => {
beforeEach(() => {
vi.clearAllMocks();
+ mockState.dismissedLoginModal = false;
+ mockState.hasAccess = undefined;
+ mockState.pausedAuthAction = null;
+ (useMinerHosting as Mock).mockReturnValue({ mode: "direct" });
(useIsAwake as Mock).mockReturnValue(true);
(useIsSleeping as Mock).mockReturnValue(false);
});
+ test("labels the power actions button", () => {
+ const { getByLabelText, getByTestId } = render(
+
+
+
+
+ ,
+ );
+
+ expect(getByLabelText("Power actions")).toBeInTheDocument();
+ expect(getByTestId(powerButton)).toHaveClass("!h-8", "!w-8", "!p-0");
+ expect(getByTestId(powerButton).querySelector("svg")?.parentElement).toHaveClass("h-4", "shrink-0");
+ });
+
test("renders power widget popover with reboot and sleep if miner is running", () => {
(useIsAwake as Mock).mockReturnValue(true);
@@ -70,6 +115,23 @@ describe("Power Widget", () => {
expect(queryByTestId(popoverWakeUpButton)).not.toBeInTheDocument();
});
+ test("opens reboot confirmation directly in fleet-hosted mode", () => {
+ (useMinerHosting as Mock).mockReturnValue({ mode: "fleet" });
+
+ const { getByTestId } = render(
+
+
+
+
+ ,
+ );
+
+ fireEvent.click(getByTestId(powerButton));
+ fireEvent.click(getByTestId(popoverRebootButton));
+
+ expect(getByTestId("warn-reboot-dialog")).toBeInTheDocument();
+ });
+
test("renders power widget popover with reboot and wake up if miner is stopped", () => {
(useIsAwake as Mock).mockReturnValue(false);
diff --git a/client/src/protoOS/components/PageHeader/Power/PowerWidget.tsx b/client/src/protoOS/components/PageHeader/Power/PowerWidget.tsx
index 03025cfaf..91cb3a62b 100644
--- a/client/src/protoOS/components/PageHeader/Power/PowerWidget.tsx
+++ b/client/src/protoOS/components/PageHeader/Power/PowerWidget.tsx
@@ -4,6 +4,7 @@ import WidgetWrapper from "../WidgetWrapper";
import PowerPopover from "./PowerPopover";
import { ErrorProps } from "@/protoOS/api/apiResponseTypes";
import { EnteringSleepDialog, RebootingDialog, WarnRebootDialog, WarnSleepDialog } from "@/protoOS/components/Power";
+import { useMinerHosting } from "@/protoOS/contexts/MinerHostingContext";
import { useAccessToken } from "@/protoOS/store";
import {
AUTH_ACTIONS,
@@ -46,6 +47,8 @@ const PowerWidget = ({
const { triggerRef: WidgetRef } = useResponsivePopover();
const isAwake = useIsAwake();
const isSleeping = useIsSleeping();
+ const { mode } = useMinerHosting();
+ const isFleetHosted = mode === "fleet";
const [isOpen, setIsOpen] = useState(shouldShowPopover);
const [warnReboot, setWarnReboot] = useState(false);
@@ -57,7 +60,9 @@ const PowerWidget = ({
const pausedAuthAction = usePausedAuthAction();
const setPausedAuthAction = useSetPausedAuthAction();
- const { checkAccess, hasAccess, setHasAccess } = useAccessToken(!!pausedAuthAction && !dismissedLoginModal);
+ const { checkAccess, hasAccess, setHasAccess } = useAccessToken(
+ !isFleetHosted && !!pausedAuthAction && !dismissedLoginModal,
+ );
const onClickOutside = useCallback(() => {
setIsOpen(false);
@@ -101,6 +106,10 @@ const PowerWidget = ({
const handleRebootButton = () => {
setIsOpen(false);
+ if (isFleetHosted) {
+ setWarnReboot(true);
+ return;
+ }
setPausedAuthAction(AUTH_ACTIONS.reboot);
checkAccess();
};
@@ -113,6 +122,10 @@ const PowerWidget = ({
const handleSleepButton = () => {
setIsOpen(false);
+ if (isFleetHosted) {
+ setWarnSleep(true);
+ return;
+ }
setPausedAuthAction(AUTH_ACTIONS.sleep);
checkAccess();
};
@@ -166,11 +179,14 @@ const PowerWidget = ({
setIsOpen((prev) => !prev)}
- className="w-[28px] p-0 text-text-primary"
+ className="!h-8 !w-8 !p-0 text-text-primary"
isOpen={isOpen}
testId="power-button"
+ ariaLabel="Power actions"
+ ariaHasPopup="menu"
+ ariaExpanded={isOpen}
>
-
+
{isOpen ? (
diff --git a/client/src/protoOS/contexts/MinerHostingContext/MinerHostingContext.tsx b/client/src/protoOS/contexts/MinerHostingContext/MinerHostingContext.tsx
index 69011c8eb..383d6b44d 100644
--- a/client/src/protoOS/contexts/MinerHostingContext/MinerHostingContext.tsx
+++ b/client/src/protoOS/contexts/MinerHostingContext/MinerHostingContext.tsx
@@ -2,6 +2,19 @@ import { createContext, ReactNode, useMemo } from "react";
import { Api, RequestParams } from "@/protoOS/api/generatedApi";
import useMinerStore from "@/protoOS/store/useMinerStore";
+export type MinerHostingMode = "direct" | "fleet";
+
+export type MinerHostingMetadata = {
+ minerName?: string;
+ ipAddress?: string;
+ macAddress?: string;
+ firmwareVersion?: string;
+};
+
+// Stable identity for the absent-metadata case so consumers' memoization
+// (useMinerHosting) isn't busted by a fresh `{}` on every provider render.
+const EMPTY_METADATA: MinerHostingMetadata = {};
+
// Read the access token at request time so every call picks up the latest
// value from the store. Using setSecurityData from a useEffect races against
// child useEffects (which fire first on initial mount), so the first fetch
@@ -16,20 +29,17 @@ const securityWorker = (): RequestParams | void => {
};
};
-const CreateApi = (baseUrl: string) => {
- const url = (baseUrl.length ? "/" : "") + baseUrl;
+const CreateApi = (baseUrl: string, mode: MinerHostingMode) => {
+ const url = baseUrl.length ? (baseUrl.startsWith("/") ? baseUrl : `/${baseUrl}`) : "";
const instance = new Api({
baseUrl: url,
- securityWorker,
+ securityWorker: mode === "direct" ? securityWorker : undefined,
// Require auth on all requests by default; firmware now gates nearly every
// endpoint. Callers of truly public endpoints (system/status, pairing/info)
// must pass { secure: false } to opt out.
baseApiParams: { secure: true },
});
- // TODO: remove this when done with development
- (window as any).api = instance.api;
-
return instance;
};
@@ -39,12 +49,16 @@ type MinerHostingContextType = {
api: ApiT | null;
minerRoot: string;
closeButton: ReactNode | null;
+ mode: MinerHostingMode;
+ metadata: MinerHostingMetadata;
};
const MinerHostingContext = createContext
({
api: null,
minerRoot: "",
closeButton: null,
+ mode: "direct",
+ metadata: EMPTY_METADATA,
});
type MinerHostingProviderProps = {
@@ -52,6 +66,8 @@ type MinerHostingProviderProps = {
baseUrl?: string;
minerRoot?: string;
closeButton?: ReactNode | null;
+ mode?: MinerHostingMode;
+ metadata?: MinerHostingMetadata;
};
export const MinerHostingProvider = ({
@@ -59,12 +75,16 @@ export const MinerHostingProvider = ({
baseUrl = "",
minerRoot = "",
closeButton = null,
+ mode = "direct",
+ metadata = EMPTY_METADATA,
}: MinerHostingProviderProps) => {
- const instance = useMemo(() => CreateApi(baseUrl), [baseUrl]);
+ const instance = useMemo(() => CreateApi(baseUrl, mode), [baseUrl, mode]);
const api = instance.api;
return (
- {children}
+
+ {children}
+
);
};
diff --git a/client/src/protoOS/contexts/MinerHostingContext/useMinerHosting.ts b/client/src/protoOS/contexts/MinerHostingContext/useMinerHosting.ts
index a33fcd0ea..f99e7199f 100644
--- a/client/src/protoOS/contexts/MinerHostingContext/useMinerHosting.ts
+++ b/client/src/protoOS/contexts/MinerHostingContext/useMinerHosting.ts
@@ -2,7 +2,10 @@ import { useContext, useMemo } from "react";
import MinerHostingContext from "./MinerHostingContext";
export const useMinerHosting = () => {
- const { api, minerRoot, closeButton } = useContext(MinerHostingContext);
+ const { api, minerRoot, closeButton, mode, metadata } = useContext(MinerHostingContext);
- return useMemo(() => ({ api, minerRoot, closeButton }), [api, minerRoot, closeButton]);
+ return useMemo(
+ () => ({ api, minerRoot, closeButton, mode, metadata }),
+ [api, minerRoot, closeButton, mode, metadata],
+ );
};
diff --git a/client/src/protoOS/features/kpis/components/Efficiency/Efficiency.tsx b/client/src/protoOS/features/kpis/components/Efficiency/Efficiency.tsx
index 88c517b23..59577c0db 100644
--- a/client/src/protoOS/features/kpis/components/Efficiency/Efficiency.tsx
+++ b/client/src/protoOS/features/kpis/components/Efficiency/Efficiency.tsx
@@ -52,20 +52,20 @@ const Efficiency = () => {
const aggregates = miner?.efficiency?.timeSeries?.aggregates;
const lowestPerformer = useMemo(() => {
- if (!hashboards) return undefined;
+ if (hashboards.length === 0) return undefined;
let lowestSlot: number | undefined;
let lowestAvg = -Infinity; // For efficiency, lower is worse, so we want highest value (worst efficiency)
hashboards.forEach((hashboard) => {
const hashboardAvg = hashboard.efficiency?.timeSeries?.aggregates?.avg?.value;
- if (!!hashboardAvg && hashboardAvg > lowestAvg) {
+ if (typeof hashboardAvg === "number" && hashboardAvg > lowestAvg) {
lowestAvg = hashboardAvg;
lowestSlot = useMinerStore.getState().hardware.getSlotByHbSn(hashboard.serial);
}
});
- return lowestSlot ? "Hashboard " + lowestSlot : undefined;
+ return lowestSlot === undefined ? undefined : "Hashboard " + lowestSlot;
}, [hashboards]);
return (
diff --git a/client/src/protoOS/features/kpis/components/Hashrate/Hashrate.tsx b/client/src/protoOS/features/kpis/components/Hashrate/Hashrate.tsx
index 29feaf54a..6afb513cd 100644
--- a/client/src/protoOS/features/kpis/components/Hashrate/Hashrate.tsx
+++ b/client/src/protoOS/features/kpis/components/Hashrate/Hashrate.tsx
@@ -52,20 +52,20 @@ const Hashrate = () => {
const aggregates = miner?.hashrate?.timeSeries?.aggregates;
const lowestPerformer = useMemo(() => {
- if (!hashboards) return undefined;
+ if (hashboards.length === 0) return undefined;
let lowestSlot: number | undefined;
let lowestAvg = Infinity;
hashboards.forEach((hashboard) => {
const hashboardAvg = hashboard.hashrate?.timeSeries?.aggregates?.avg?.value;
- if (!!hashboardAvg && hashboardAvg < lowestAvg) {
+ if (typeof hashboardAvg === "number" && hashboardAvg < lowestAvg) {
lowestAvg = hashboardAvg;
lowestSlot = useMinerStore.getState().hardware.getSlotByHbSn(hashboard.serial);
}
});
- return lowestSlot ? "Hashboard " + lowestSlot : undefined;
+ return lowestSlot === undefined ? undefined : "Hashboard " + lowestSlot;
}, [hashboards]);
return (
diff --git a/client/src/protoOS/features/kpis/components/Temperature/Temperature.tsx b/client/src/protoOS/features/kpis/components/Temperature/Temperature.tsx
index 3cf21adeb..6aae374b5 100644
--- a/client/src/protoOS/features/kpis/components/Temperature/Temperature.tsx
+++ b/client/src/protoOS/features/kpis/components/Temperature/Temperature.tsx
@@ -59,20 +59,20 @@ const Temperature = () => {
const aggregates = miner?.temperature?.timeSeries?.aggregates;
const lowestPerformer = useMemo(() => {
- if (!hashboards) return undefined;
+ if (hashboards.length === 0) return undefined;
let hottestSlot: number | undefined;
let hottestTemp = -Infinity;
hashboards.forEach((hashboard) => {
const hashboardMax = hashboard.temperature?.timeSeries?.aggregates?.max?.value;
- if (!!hashboardMax && hashboardMax > hottestTemp) {
+ if (typeof hashboardMax === "number" && hashboardMax > hottestTemp) {
hottestTemp = hashboardMax;
hottestSlot = useMinerStore.getState().hardware.getSlotByHbSn(hashboard.serial);
}
});
- return hottestSlot ? "Hashboard " + hottestSlot : undefined;
+ return hottestSlot === undefined ? undefined : "Hashboard " + hottestSlot;
}, [hashboards]);
return (
diff --git a/client/src/protoOS/features/settings/components/Cooling/Cooling.test.tsx b/client/src/protoOS/features/settings/components/Cooling/Cooling.test.tsx
new file mode 100644
index 000000000..a26d2d723
--- /dev/null
+++ b/client/src/protoOS/features/settings/components/Cooling/Cooling.test.tsx
@@ -0,0 +1,57 @@
+import { render, screen } from "@testing-library/react";
+import { beforeEach, describe, expect, test, vi } from "vitest";
+import Cooling from "./Cooling";
+import { useCoolingStatus } from "@/protoOS/api";
+import { useCoolingMode, useFansTelemetry, useIsSleeping } from "@/protoOS/store";
+
+vi.mock("@/protoOS/api", () => ({
+ useCoolingStatus: vi.fn(),
+}));
+
+vi.mock("@/protoOS/store", () => ({
+ useCoolingMode: vi.fn(),
+ useFansTelemetry: vi.fn(),
+ useIsSleeping: vi.fn(),
+}));
+
+vi.mock("@/protoOS/components/Power", () => ({
+ EnteringSleepDialog: () => null,
+}));
+
+vi.mock("@/shared/features/toaster", () => ({
+ pushToast: vi.fn(() => 1),
+ updateToast: vi.fn(),
+}));
+
+describe("Cooling", () => {
+ beforeEach(() => {
+ vi.clearAllMocks();
+ vi.mocked(useCoolingStatus).mockReturnValue({
+ data: undefined,
+ error: undefined,
+ loaded: true,
+ pending: false,
+ setCooling: vi.fn(),
+ } as ReturnType);
+ vi.mocked(useFansTelemetry).mockReturnValue([]);
+ vi.mocked(useIsSleeping).mockReturnValue(false);
+ });
+
+ test("selects air cooled when the store already has Auto mode on mount", () => {
+ vi.mocked(useCoolingMode).mockReturnValue("Auto");
+
+ render();
+
+ expect(screen.getByTestId("cooling-option-air").querySelector("input")).toBeChecked();
+ expect(screen.getByTestId("cooling-option-immersion").querySelector("input")).not.toBeChecked();
+ });
+
+ test("selects immersion cooled when the store already has Off mode on mount", () => {
+ vi.mocked(useCoolingMode).mockReturnValue("Off");
+
+ render();
+
+ expect(screen.getByTestId("cooling-option-air").querySelector("input")).not.toBeChecked();
+ expect(screen.getByTestId("cooling-option-immersion").querySelector("input")).toBeChecked();
+ });
+});
diff --git a/client/src/protoOS/features/settings/components/Cooling/Cooling.tsx b/client/src/protoOS/features/settings/components/Cooling/Cooling.tsx
index c5505052e..b7f03e967 100644
--- a/client/src/protoOS/features/settings/components/Cooling/Cooling.tsx
+++ b/client/src/protoOS/features/settings/components/Cooling/Cooling.tsx
@@ -55,6 +55,13 @@ const isAirCooledMode = (fanMode: string | undefined) => fanMode === "Auto" || f
const isImmersionMode = (fanMode: string | undefined) => fanMode === "Off";
+const coolingModeFromFanMode = (fanMode: string | undefined | null): CoolingMode | undefined => {
+ if (!fanMode) return undefined;
+ if (isAirCooledMode(fanMode)) return COOLING_MODES.air;
+ if (isImmersionMode(fanMode)) return COOLING_MODES.immersion;
+ return undefined;
+};
+
const disabledClassName = "opacity-50 pointer-events-none";
const isSelected = (
@@ -71,13 +78,15 @@ const isSelected = (
const Cooling = () => {
const { pending, setCooling } = useCoolingStatus({ poll: true });
- const [coolingMode, setCoolingMode] = useState();
const isSleeping = useIsSleeping();
const storeCoolingMode = useCoolingMode();
+ const [coolingMode, setCoolingMode] = useState(() =>
+ coolingModeFromFanMode(storeCoolingMode),
+ );
const fans = useFansTelemetry();
const [userSelectedCoolingMode, setUserSelectedCoolingMode] = useState();
- const [loading, setLoading] = useState(true);
+ const [loading, setLoading] = useState(() => coolingModeFromFanMode(storeCoolingMode) === undefined);
const [showImmersionModal, setShowImmersionModal] = useState(false);
const [showLearnMoreModal, setShowLearnMoreModal] = useState(false);
const [showSleepDialog, setShowSleepDialog] = useState(false);
@@ -86,14 +95,10 @@ const Cooling = () => {
const [prevStoreCoolingMode, setPrevStoreCoolingMode] = useState(storeCoolingMode);
if (prevStoreCoolingMode !== storeCoolingMode) {
setPrevStoreCoolingMode(storeCoolingMode);
- if (storeCoolingMode) {
- if (isAirCooledMode(storeCoolingMode)) {
- setCoolingMode(COOLING_MODES.air);
- setLoading(false);
- } else if (isImmersionMode(storeCoolingMode)) {
- setCoolingMode(COOLING_MODES.immersion);
- setLoading(false);
- }
+ const nextCoolingMode = coolingModeFromFanMode(storeCoolingMode);
+ if (nextCoolingMode) {
+ setCoolingMode(nextCoolingMode);
+ setLoading(false);
}
}
diff --git a/client/src/protoOS/hooks/useWakeMiner/useWakeMiner.ts b/client/src/protoOS/hooks/useWakeMiner/useWakeMiner.ts
index 815a6b689..e9fb9d80c 100644
--- a/client/src/protoOS/hooks/useWakeMiner/useWakeMiner.ts
+++ b/client/src/protoOS/hooks/useWakeMiner/useWakeMiner.ts
@@ -1,6 +1,7 @@
import { useCallback, useEffect, useRef, useState } from "react";
import { useMiningStart, useMiningStatus } from "@/protoOS/api";
import { ErrorProps } from "@/protoOS/api/apiResponseTypes";
+import { useMinerHosting } from "@/protoOS/contexts/MinerHostingContext";
import { useAccessToken } from "@/protoOS/store";
import {
AUTH_ACTIONS,
@@ -34,7 +35,9 @@ export const useWakeMiner = ({ afterWake, onSuccess, onError }: UseWakeMinerProp
const setDismissedLoginModal = useSetDismissedLoginModal();
const pausedAuthAction = usePausedAuthAction();
const setPausedAuthAction = useSetPausedAuthAction();
- const { checkAccess, hasAccess } = useAccessToken(!!pausedAuthAction && !dismissedLoginModal);
+ const { mode } = useMinerHosting();
+ const isFleetHosted = mode === "fleet";
+ const { checkAccess, hasAccess } = useAccessToken(!isFleetHosted && !!pausedAuthAction && !dismissedLoginModal);
const afterWakeRef = useRef(afterWake);
const onSuccessRef = useRef(onSuccess);
const onErrorRef = useRef(onError);
@@ -146,9 +149,14 @@ export const useWakeMiner = ({ afterWake, onSuccess, onError }: UseWakeMinerProp
}, [hasAccess, pausedAuthAction, setPausedAuthAction, showWakeDialog, hideWakeDialog, handleWakeConfirm]);
const wakeMiner = useCallback(() => {
+ if (isFleetHosted) {
+ showWakeDialog(handleWakeConfirm, () => hideWakeDialog());
+ return;
+ }
+
setPausedAuthAction(AUTH_ACTIONS.wake);
checkAccess();
- }, [checkAccess, setPausedAuthAction]);
+ }, [checkAccess, handleWakeConfirm, hideWakeDialog, isFleetHosted, setPausedAuthAction, showWakeDialog]);
return {
wakeMiner,
diff --git a/client/src/protoOS/store/hooks/useAuth.test.ts b/client/src/protoOS/store/hooks/useAuth.test.ts
index a7af8e1b0..47f3c03d6 100644
--- a/client/src/protoOS/store/hooks/useAuth.test.ts
+++ b/client/src/protoOS/store/hooks/useAuth.test.ts
@@ -6,6 +6,7 @@ const mockRefresh = vi.fn();
const mockLogout = vi.fn();
const mockSetShowLoginModal = vi.fn();
const mockUseLocation = vi.hoisted(() => vi.fn());
+const mockUseMinerHosting = vi.hoisted(() => vi.fn());
const mockSetDefaultPasswordActive = vi.fn();
const mockGetState = vi.fn();
@@ -13,6 +14,10 @@ vi.mock("@/protoOS/api/hooks/useRefresh", () => ({
useRefresh: () => mockRefresh,
}));
+vi.mock("@/protoOS/contexts/MinerHostingContext", () => ({
+ useMinerHosting: mockUseMinerHosting,
+}));
+
vi.mock("../useMinerStore", () => ({
default: Object.assign(
vi.fn((selector: any) =>
@@ -55,6 +60,7 @@ describe("useAuthErrors", () => {
vi.clearAllMocks();
__resetRefreshInFlightForTest();
mockUseLocation.mockReturnValue({ pathname: "/" });
+ mockUseMinerHosting.mockReturnValue({ mode: "direct" });
mockGetState.mockReturnValue({
auth: {
authTokens: {
@@ -92,6 +98,25 @@ describe("useAuthErrors", () => {
expect(onSuccess).toHaveBeenCalledWith("new-token");
});
+ test("does not run direct miner refresh or show the login modal for fleet-hosted 401s", () => {
+ mockUseMinerHosting.mockReturnValue({ mode: "fleet" });
+ const onError = vi.fn();
+
+ const { result } = renderHook(() => useAuthErrors());
+
+ const error = { status: 401, error: { message: "Unauthorized" } };
+ const returnValue = result.current.handleAuthErrors({
+ error,
+ onError,
+ });
+
+ expect(returnValue).toBeUndefined();
+ expect(mockRefresh).not.toHaveBeenCalled();
+ expect(mockLogout).not.toHaveBeenCalled();
+ expect(mockSetShowLoginModal).not.toHaveBeenCalled();
+ expect(onError).toHaveBeenCalledWith(error);
+ });
+
test("uses the latest refresh token from store when handling 401s", () => {
mockGetState.mockReturnValue({
auth: {
diff --git a/client/src/protoOS/store/hooks/useAuth.ts b/client/src/protoOS/store/hooks/useAuth.ts
index be73e0f7e..01d2afb04 100644
--- a/client/src/protoOS/store/hooks/useAuth.ts
+++ b/client/src/protoOS/store/hooks/useAuth.ts
@@ -4,6 +4,7 @@ import useMinerStore from "../useMinerStore";
import { ErrorProps } from "@/protoOS/api/apiResponseTypes";
import { isDefaultPasswordActiveError } from "@/protoOS/api/defaultPasswordContract";
import { useRefresh } from "@/protoOS/api/hooks/useRefresh";
+import { useMinerHosting } from "@/protoOS/contexts/MinerHostingContext";
import { isAuthRequiredPath } from "@/protoOS/routeAuth";
// =============================================================================
@@ -70,9 +71,16 @@ export const useAuthErrors = () => {
const setShowLoginModal = useMinerStore((state) => state.ui.setShowLoginModal);
const setDefaultPasswordActive = useMinerStore((state) => state.minerStatus.setDefaultPasswordActive);
const refresh = useRefresh();
+ const { mode } = useMinerHosting();
+ const isFleetHosted = mode === "fleet";
const handleAuthErrors = useCallback(
({ error, onError, onSuccess }: HandleAuthErrorsProps) => {
+ if (isFleetHosted) {
+ onError?.(error);
+ return;
+ }
+
// 403 with DEFAULT_PASSWORD_ACTIVE means the device still has its factory
// password. Surface this in the store so the UI can prompt a password change.
if (isDefaultPasswordActiveError(error)) {
@@ -111,7 +119,7 @@ export const useAuthErrors = () => {
}
onError?.(error);
},
- [refresh, logout, setShowLoginModal, setDefaultPasswordActive],
+ [isFleetHosted, refresh, logout, setShowLoginModal, setDefaultPasswordActive],
);
return useMemo(
diff --git a/client/src/protoOS/store/hooks/useAuthRetry.test.ts b/client/src/protoOS/store/hooks/useAuthRetry.test.ts
index e79d427a7..319cbd1fd 100644
--- a/client/src/protoOS/store/hooks/useAuthRetry.test.ts
+++ b/client/src/protoOS/store/hooks/useAuthRetry.test.ts
@@ -3,6 +3,7 @@ import { beforeEach, describe, expect, test, vi } from "vitest";
import { useAuthRetry } from "./useAuthRetry";
const mockHandleAuthErrors = vi.fn();
+const mockUseMinerHosting = vi.hoisted(() => vi.fn());
const mockGetState = vi.fn();
let currentAccessToken = "test-token";
@@ -21,9 +22,14 @@ vi.mock("./useAuth", () => ({
useAuthErrors: vi.fn(() => ({ handleAuthErrors: mockHandleAuthErrors })),
}));
+vi.mock("@/protoOS/contexts/MinerHostingContext", () => ({
+ useMinerHosting: mockUseMinerHosting,
+}));
+
describe("useAuthRetry", () => {
beforeEach(() => {
vi.clearAllMocks();
+ mockUseMinerHosting.mockReturnValue({ mode: "direct" });
currentAccessToken = "test-token";
mockGetState.mockImplementation(() => ({
auth: {
@@ -69,6 +75,21 @@ describe("useAuthRetry", () => {
});
});
+ test("does not use direct miner bearer auth or refresh retry in fleet-hosted mode", async () => {
+ mockUseMinerHosting.mockReturnValue({ mode: "fleet" });
+ const error = { status: 401, error: { message: "Unauthorized" } };
+ const request = vi.fn().mockRejectedValue(error);
+ const onError = vi.fn();
+
+ const { result } = renderHook(() => useAuthRetry());
+
+ await result.current({ request, onError });
+
+ expect(request).toHaveBeenCalledWith({ secure: false });
+ expect(onError).toHaveBeenCalledWith(error);
+ expect(mockHandleAuthErrors).not.toHaveBeenCalled();
+ });
+
test("retries with fresh token on successful refresh", async () => {
const error = { status: 401, error: { message: "Unauthorized" } };
const request = vi.fn().mockRejectedValueOnce(error).mockResolvedValueOnce("retry-result");
diff --git a/client/src/protoOS/store/hooks/useAuthRetry.ts b/client/src/protoOS/store/hooks/useAuthRetry.ts
index 4537b692b..51abf2929 100644
--- a/client/src/protoOS/store/hooks/useAuthRetry.ts
+++ b/client/src/protoOS/store/hooks/useAuthRetry.ts
@@ -3,8 +3,9 @@ import useMinerStore from "../useMinerStore";
import { useAuthErrors } from "./useAuth";
import { ErrorProps } from "@/protoOS/api/apiResponseTypes";
import { RequestParams } from "@/protoOS/api/generatedApi";
+import { useMinerHosting } from "@/protoOS/contexts/MinerHostingContext";
-type AuthRequestParams = RequestParams & { headers: { Authorization: string } };
+type AuthRequestParams = RequestParams & { headers?: { Authorization?: string } };
interface AuthRetryOptions {
request: (params: AuthRequestParams) => Promise;
@@ -22,21 +23,25 @@ interface AuthRetryOptions {
*/
export const useAuthRetry = () => {
const { handleAuthErrors } = useAuthErrors();
+ const { mode } = useMinerHosting();
+ const isFleetHosted = mode === "fleet";
return useCallback(
({ request, onSuccess, onError, shouldRetry }: AuthRetryOptions): Promise => {
- const authRequestParams: AuthRequestParams = {
- secure: false,
- headers: {
- Authorization: `Bearer ${useMinerStore.getState().auth.authTokens.accessToken?.value || ""}`,
- },
- };
+ const authRequestParams: AuthRequestParams = isFleetHosted
+ ? { secure: false }
+ : {
+ secure: false,
+ headers: {
+ Authorization: `Bearer ${useMinerStore.getState().auth.authTokens.accessToken?.value || ""}`,
+ },
+ };
const execute = (params: AuthRequestParams, isRetry = false): Promise =>
request(params)
.then((result) => onSuccess?.(result))
.catch((error) => {
- if (isRetry || (shouldRetry && !shouldRetry(error))) {
+ if (isFleetHosted || isRetry || (shouldRetry && !shouldRetry(error))) {
onError?.(error);
return;
}
@@ -56,6 +61,6 @@ export const useAuthRetry = () => {
return execute(authRequestParams);
},
- [handleAuthErrors],
+ [handleAuthErrors, isFleetHosted],
);
};
diff --git a/plugin/proto/go.mod b/plugin/proto/go.mod
index 9087f5b06..77e9d65a7 100644
--- a/plugin/proto/go.mod
+++ b/plugin/proto/go.mod
@@ -4,7 +4,6 @@ go 1.25.4
require (
github.com/block/proto-fleet/server v0.0.0-20260612045813-75933fce45c2
- github.com/golang-jwt/jwt/v5 v5.3.1
github.com/hashicorp/go-plugin v1.8.0
github.com/moby/moby/api v1.54.2
github.com/moby/moby/client v0.4.1
diff --git a/plugin/proto/go.sum b/plugin/proto/go.sum
index cbe76afcb..1a25d2458 100644
--- a/plugin/proto/go.sum
+++ b/plugin/proto/go.sum
@@ -49,8 +49,6 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
-github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY=
-github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
diff --git a/proto/fleetmanagement/v1/fleetmanagement.proto b/proto/fleetmanagement/v1/fleetmanagement.proto
index 8fdb7a647..255eaaac9 100644
--- a/proto/fleetmanagement/v1/fleetmanagement.proto
+++ b/proto/fleetmanagement/v1/fleetmanagement.proto
@@ -155,6 +155,12 @@ message MinerStateSnapshot {
// device is not assigned at that level; groups is empty when the device is
// not a member of any group.
common.v1.PlacementRefs placement = 28;
+
+ // True when Fleet can open an embedded web management view for this miner.
+ // Availability is computed from driver support, pairing state, and routing
+ // ownership; unsupported or fleet-node-owned devices should use their external
+ // URL or typed control-stream commands instead.
+ bool embedded_web_view_available = 29;
}
// Removed MinerComponentStatus and ComponentStatus - now using error-based filtering
diff --git a/server/cmd/fleetd/main.go b/server/cmd/fleetd/main.go
index a23fdcee6..e4cba531d 100644
--- a/server/cmd/fleetd/main.go
+++ b/server/cmd/fleetd/main.go
@@ -108,6 +108,7 @@ import (
foremanImportHandler "github.com/block/proto-fleet/server/internal/handlers/foremanimport"
"github.com/block/proto-fleet/server/internal/handlers/interceptors"
"github.com/block/proto-fleet/server/internal/handlers/middleware"
+ minerProxyHandler "github.com/block/proto-fleet/server/internal/handlers/minerproxy"
"github.com/block/proto-fleet/server/internal/handlers/networkinfo"
notificationsHandler "github.com/block/proto-fleet/server/internal/handlers/notifications"
"github.com/block/proto-fleet/server/internal/handlers/onboarding"
@@ -588,6 +589,7 @@ func start(config *Config) error {
mux.Handle("GET /api/v1/firmware/files", firmwareHandler.NewListFilesHandler(filesService, sessionSvc, userStore))
mux.Handle("DELETE /api/v1/firmware/files/{fileId}", firmwareHandler.NewDeleteFileHandler(filesService, sessionSvc, userStore))
mux.Handle("DELETE /api/v1/firmware/files", firmwareHandler.NewDeleteAllFilesHandler(filesService, sessionSvc, userStore))
+ mux.Handle("/miners/{deviceIdentifier}/api/v1/{rest...}", minerProxyHandler.NewHandler(conn, sessionSvc, userStore, permissionResolver, encryptSvc))
chunkedCleanupCtx, chunkedCleanupCancel := context.WithCancel(context.Background())
go chunkedMgr.StartCleanup(chunkedCleanupCtx, config.Files.ChunkedUploadSessionTTL)
diff --git a/server/generated/grpc/fleetmanagement/v1/fleetmanagement.pb.go b/server/generated/grpc/fleetmanagement/v1/fleetmanagement.pb.go
index a73e96b98..07be5496b 100644
--- a/server/generated/grpc/fleetmanagement/v1/fleetmanagement.pb.go
+++ b/server/generated/grpc/fleetmanagement/v1/fleetmanagement.pb.go
@@ -572,9 +572,14 @@ type MinerStateSnapshot struct {
// Placement references for this device. Individual refs are unset when the
// device is not assigned at that level; groups is empty when the device is
// not a member of any group.
- Placement *v1.PlacementRefs `protobuf:"bytes,28,opt,name=placement,proto3" json:"placement,omitempty"`
- unknownFields protoimpl.UnknownFields
- sizeCache protoimpl.SizeCache
+ Placement *v1.PlacementRefs `protobuf:"bytes,28,opt,name=placement,proto3" json:"placement,omitempty"`
+ // True when Fleet can open an embedded web management view for this miner.
+ // Availability is computed from driver support, pairing state, and routing
+ // ownership; unsupported or fleet-node-owned devices should use their external
+ // URL or typed control-stream commands instead.
+ EmbeddedWebViewAvailable bool `protobuf:"varint,29,opt,name=embedded_web_view_available,json=embeddedWebViewAvailable,proto3" json:"embedded_web_view_available,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
}
func (x *MinerStateSnapshot) Reset() {
@@ -761,6 +766,13 @@ func (x *MinerStateSnapshot) GetPlacement() *v1.PlacementRefs {
return nil
}
+func (x *MinerStateSnapshot) GetEmbeddedWebViewAvailable() bool {
+ if x != nil {
+ return x.EmbeddedWebViewAvailable
+ }
+ return false
+}
+
// Request to list miners with their metadata
// Returns paginated list of miners with identification info and status
// Use GetBatchMinerTelemetry to fetch telemetry for specific miners after initial load
@@ -2948,7 +2960,7 @@ var file_fleetmanagement_v1_fleetmanagement_proto_rawDesc = string([]byte{
0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x7a, 0x6f, 0x6e, 0x65, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x62, 0x75, 0x66, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61,
0x74, 0x65, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
- 0x6f, 0x22, 0xfb, 0x08, 0x0a, 0x12, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65,
+ 0x6f, 0x22, 0xba, 0x09, 0x0a, 0x12, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65,
0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x2b, 0x0a, 0x11, 0x64, 0x65, 0x76, 0x69,
0x63, 0x65, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x10, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74,
@@ -3013,555 +3025,559 @@ var file_fleetmanagement_v1_fleetmanagement_proto_rawDesc = string([]byte{
0x0a, 0x09, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x1c, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x18, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6c,
0x61, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x66, 0x73, 0x52, 0x09, 0x70, 0x6c, 0x61,
- 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4a, 0x04, 0x08, 0x10, 0x10, 0x11, 0x4a, 0x04, 0x08, 0x14,
- 0x10, 0x15, 0x4a, 0x04, 0x08, 0x15, 0x10, 0x16, 0x4a, 0x04, 0x08, 0x19, 0x10, 0x1a, 0x4a, 0x04,
- 0x08, 0x1a, 0x10, 0x1b, 0x4a, 0x04, 0x08, 0x1b, 0x10, 0x1c, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65,
- 0x52, 0x0c, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x0a,
- 0x72, 0x61, 0x63, 0x6b, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x52, 0x07, 0x73, 0x69, 0x74, 0x65,
- 0x5f, 0x69, 0x64, 0x52, 0x0a, 0x73, 0x69, 0x74, 0x65, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x52,
- 0x0e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x22,
- 0xc9, 0x01, 0x0a, 0x1e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61,
- 0x74, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
- 0x73, 0x74, 0x12, 0x27, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18,
- 0x01, 0x20, 0x01, 0x28, 0x05, 0x42, 0x0a, 0xba, 0x48, 0x07, 0x1a, 0x05, 0x18, 0xe8, 0x07, 0x28,
- 0x00, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x63,
- 0x75, 0x72, 0x73, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x75, 0x72,
- 0x73, 0x6f, 0x72, 0x12, 0x3b, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20,
- 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67,
- 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x69,
- 0x73, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72,
- 0x12, 0x29, 0x0a, 0x04, 0x73, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15,
- 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x6f, 0x72, 0x74, 0x43,
- 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x04, 0x73, 0x6f, 0x72, 0x74, 0x22, 0xeb, 0x05, 0x0a, 0x0f,
- 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12,
- 0x45, 0x0a, 0x0d, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
- 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61,
- 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69,
- 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x0c, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65,
- 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x4c, 0x0a, 0x15, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f,
- 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18,
- 0x04, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2e, 0x76,
- 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52,
- 0x13, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x54,
- 0x79, 0x70, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x18, 0x05,
- 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x12, 0x4c, 0x0a, 0x10,
- 0x70, 0x61, 0x69, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73,
- 0x18, 0x06, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61,
- 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x69, 0x72,
- 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x0f, 0x70, 0x61, 0x69, 0x72, 0x69,
- 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x72,
- 0x6f, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x03, 0x52, 0x08, 0x67,
- 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x61, 0x63, 0x6b, 0x5f,
- 0x69, 0x64, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x03, 0x52, 0x07, 0x72, 0x61, 0x63, 0x6b, 0x49,
- 0x64, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x5f, 0x76,
- 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x66,
- 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12,
- 0x18, 0x0a, 0x05, 0x7a, 0x6f, 0x6e, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x42, 0x02,
- 0x18, 0x01, 0x52, 0x05, 0x7a, 0x6f, 0x6e, 0x65, 0x73, 0x12, 0x4d, 0x0a, 0x0e, 0x6e, 0x75, 0x6d,
- 0x65, 0x72, 0x69, 0x63, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28,
- 0x0b, 0x32, 0x26, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d,
- 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x52, 0x61,
- 0x6e, 0x67, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x0d, 0x6e, 0x75, 0x6d, 0x65, 0x72,
- 0x69, 0x63, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x70, 0x5f, 0x63,
- 0x69, 0x64, 0x72, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x69, 0x70, 0x43, 0x69,
- 0x64, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x69, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18,
- 0x0d, 0x20, 0x03, 0x28, 0x03, 0x52, 0x07, 0x73, 0x69, 0x74, 0x65, 0x49, 0x64, 0x73, 0x12, 0x2d,
- 0x0a, 0x12, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x75, 0x6e, 0x61, 0x73, 0x73, 0x69,
- 0x67, 0x6e, 0x65, 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x69, 0x6e, 0x63, 0x6c,
- 0x75, 0x64, 0x65, 0x55, 0x6e, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x12, 0x21, 0x0a,
- 0x0c, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x0f, 0x20,
- 0x03, 0x28, 0x03, 0x52, 0x0b, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x64, 0x73,
- 0x12, 0x2e, 0x0a, 0x13, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x6e, 0x6f, 0x5f, 0x62,
- 0x75, 0x69, 0x6c, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x69,
- 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x4e, 0x6f, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x6e, 0x67,
- 0x12, 0x2f, 0x0a, 0x09, 0x7a, 0x6f, 0x6e, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x11, 0x20,
- 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e,
- 0x5a, 0x6f, 0x6e, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x08, 0x7a, 0x6f, 0x6e, 0x65, 0x4b, 0x65, 0x79,
- 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x6e, 0x6f, 0x5f,
- 0x72, 0x61, 0x63, 0x6b, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x69, 0x6e, 0x63, 0x6c,
- 0x75, 0x64, 0x65, 0x4e, 0x6f, 0x52, 0x61, 0x63, 0x6b, 0x22, 0xf6, 0x01, 0x0a, 0x12, 0x4e, 0x75,
- 0x6d, 0x65, 0x72, 0x69, 0x63, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72,
- 0x12, 0x36, 0x0a, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32,
- 0x20, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e,
- 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x46, 0x69, 0x65, 0x6c,
- 0x64, 0x52, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x2e, 0x0a, 0x03, 0x6d, 0x69, 0x6e, 0x18,
- 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
- 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61,
- 0x6c, 0x75, 0x65, 0x52, 0x03, 0x6d, 0x69, 0x6e, 0x12, 0x2e, 0x0a, 0x03, 0x6d, 0x61, 0x78, 0x18,
- 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
- 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61,
- 0x6c, 0x75, 0x65, 0x52, 0x03, 0x6d, 0x61, 0x78, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x69, 0x6e, 0x5f,
- 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52,
- 0x0c, 0x6d, 0x69, 0x6e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x12, 0x23, 0x0a,
- 0x0d, 0x6d, 0x61, 0x78, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x18, 0x05,
- 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69,
- 0x76, 0x65, 0x22, 0xaf, 0x02, 0x0a, 0x1f, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72,
- 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x52, 0x65,
- 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x06, 0x6d, 0x69, 0x6e, 0x65, 0x72, 0x73,
- 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61,
- 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x69, 0x6e, 0x65,
- 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x06,
- 0x6d, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72,
- 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x12, 0x21,
- 0x0a, 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x6d, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x03,
- 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x4d, 0x69, 0x6e, 0x65, 0x72,
- 0x73, 0x12, 0x4c, 0x0a, 0x12, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65,
- 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e,
- 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x69, 0x6e,
- 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x10, 0x74,
- 0x6f, 0x74, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12,
- 0x16, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52,
- 0x06, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x66, 0x69, 0x72, 0x6d, 0x77,
- 0x61, 0x72, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x03,
- 0x28, 0x09, 0x52, 0x10, 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x56, 0x65, 0x72, 0x73,
- 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x35, 0x0a, 0x14, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x4d,
- 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a,
- 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09,
- 0x52, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x73, 0x22, 0xe7, 0x01, 0x0a, 0x15,
- 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73,
- 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x09, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f,
- 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74,
- 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x69,
- 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74,
- 0x52, 0x09, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x12, 0x4d, 0x0a, 0x06, 0x65,
- 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x66, 0x6c,
- 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31,
- 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65,
- 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x45, 0x6e, 0x74,
- 0x72, 0x79, 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x45, 0x72,
- 0x72, 0x6f, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
- 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76,
- 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,
- 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xab, 0x01, 0x0a, 0x19, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74,
- 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x73, 0x76, 0x52, 0x65, 0x71, 0x75,
- 0x65, 0x73, 0x74, 0x12, 0x3b, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67,
- 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x69,
- 0x73, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72,
- 0x12, 0x51, 0x0a, 0x10, 0x74, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f,
- 0x75, 0x6e, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x66, 0x6c, 0x65,
- 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e,
- 0x43, 0x73, 0x76, 0x54, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x55, 0x6e,
- 0x69, 0x74, 0x52, 0x0f, 0x74, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x55,
- 0x6e, 0x69, 0x74, 0x22, 0x37, 0x0a, 0x1a, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x4d, 0x69, 0x6e,
- 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x73, 0x76, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
- 0x65, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x73, 0x76, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x73, 0x76, 0x44, 0x61, 0x74, 0x61, 0x22, 0x66, 0x0a, 0x1a,
- 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x75,
- 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x69,
- 0x74, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x03, 0x52, 0x07, 0x73, 0x69,
- 0x74, 0x65, 0x49, 0x64, 0x73, 0x12, 0x2d, 0x0a, 0x12, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65,
- 0x5f, 0x75, 0x6e, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
- 0x08, 0x52, 0x11, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x55, 0x6e, 0x61, 0x73, 0x73, 0x69,
- 0x67, 0x6e, 0x65, 0x64, 0x22, 0x83, 0x01, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x65,
- 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70,
- 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x6d, 0x69,
- 0x6e, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61,
- 0x6c, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x41, 0x0a, 0x0c, 0x73, 0x74, 0x61, 0x74, 0x65,
- 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e,
- 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x69, 0x6e,
- 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x0b, 0x73,
- 0x74, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x22, 0x55, 0x0a, 0x1e, 0x47, 0x65,
- 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x50, 0x6f, 0x6f, 0x6c, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e,
- 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x33, 0x0a, 0x11,
- 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65,
- 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52,
- 0x10, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65,
- 0x72, 0x22, 0x68, 0x0a, 0x0e, 0x50, 0x6f, 0x6f, 0x6c, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d,
- 0x65, 0x6e, 0x74, 0x12, 0x1c, 0x0a, 0x07, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x01,
- 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x06, 0x70, 0x6f, 0x6f, 0x6c, 0x49, 0x64, 0x88, 0x01,
- 0x01, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
- 0x75, 0x72, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18,
- 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x42,
- 0x0a, 0x0a, 0x08, 0x5f, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x69, 0x64, 0x22, 0x5b, 0x0a, 0x1f, 0x47,
- 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x50, 0x6f, 0x6f, 0x6c, 0x41, 0x73, 0x73, 0x69, 0x67,
- 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38,
- 0x0a, 0x05, 0x70, 0x6f, 0x6f, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e,
- 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e,
- 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6f, 0x6c, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e,
- 0x74, 0x52, 0x05, 0x70, 0x6f, 0x6f, 0x6c, 0x73, 0x22, 0x61, 0x0a, 0x0f, 0x4d, 0x69, 0x6e, 0x65,
- 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x6d,
- 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x6f, 0x64, 0x65,
- 0x6c, 0x12, 0x22, 0x0a, 0x0c, 0x6d, 0x61, 0x6e, 0x75, 0x66, 0x61, 0x63, 0x74, 0x75, 0x72, 0x65,
- 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6d, 0x61, 0x6e, 0x75, 0x66, 0x61, 0x63,
- 0x74, 0x75, 0x72, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03,
- 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x59, 0x0a, 0x1a, 0x47,
- 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x47, 0x72, 0x6f, 0x75,
- 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3b, 0x0a, 0x06, 0x66, 0x69, 0x6c,
- 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x66, 0x6c, 0x65, 0x65,
- 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d,
- 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06,
- 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x5a, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e,
- 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x73,
- 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18,
- 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e,
+ 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x3d, 0x0a, 0x1b, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64,
+ 0x65, 0x64, 0x5f, 0x77, 0x65, 0x62, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x61, 0x76, 0x61, 0x69,
+ 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x65, 0x6d, 0x62,
+ 0x65, 0x64, 0x64, 0x65, 0x64, 0x57, 0x65, 0x62, 0x56, 0x69, 0x65, 0x77, 0x41, 0x76, 0x61, 0x69,
+ 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x4a, 0x04, 0x08, 0x10, 0x10, 0x11, 0x4a, 0x04, 0x08, 0x14, 0x10,
+ 0x15, 0x4a, 0x04, 0x08, 0x15, 0x10, 0x16, 0x4a, 0x04, 0x08, 0x19, 0x10, 0x1a, 0x4a, 0x04, 0x08,
+ 0x1a, 0x10, 0x1b, 0x4a, 0x04, 0x08, 0x1b, 0x10, 0x1c, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x52,
+ 0x0c, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x0a, 0x72,
+ 0x61, 0x63, 0x6b, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x52, 0x07, 0x73, 0x69, 0x74, 0x65, 0x5f,
+ 0x69, 0x64, 0x52, 0x0a, 0x73, 0x69, 0x74, 0x65, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x52, 0x0e,
+ 0x62, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x22, 0xc9,
+ 0x01, 0x0a, 0x1e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74,
+ 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+ 0x74, 0x12, 0x27, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x05, 0x42, 0x0a, 0xba, 0x48, 0x07, 0x1a, 0x05, 0x18, 0xe8, 0x07, 0x28, 0x00,
+ 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x75,
+ 0x72, 0x73, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x75, 0x72, 0x73,
+ 0x6f, 0x72, 0x12, 0x3b, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65,
+ 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x69, 0x73,
+ 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12,
+ 0x29, 0x0a, 0x04, 0x73, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x6f, 0x72, 0x74, 0x43, 0x6f,
+ 0x6e, 0x66, 0x69, 0x67, 0x52, 0x04, 0x73, 0x6f, 0x72, 0x74, 0x22, 0xeb, 0x05, 0x0a, 0x0f, 0x4d,
+ 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x45,
+ 0x0a, 0x0d, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18,
+ 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e,
+ 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63,
+ 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x0c, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53,
+ 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x4c, 0x0a, 0x15, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63,
+ 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x04,
+ 0x20, 0x03, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2e, 0x76, 0x31,
+ 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x13,
+ 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x54, 0x79,
+ 0x70, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x18, 0x05, 0x20,
+ 0x03, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x12, 0x4c, 0x0a, 0x10, 0x70,
+ 0x61, 0x69, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x18,
+ 0x06, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e,
+ 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x69, 0x72, 0x69,
+ 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x0f, 0x70, 0x61, 0x69, 0x72, 0x69, 0x6e,
+ 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x72, 0x6f,
+ 0x75, 0x70, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x03, 0x52, 0x08, 0x67, 0x72,
+ 0x6f, 0x75, 0x70, 0x49, 0x64, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x61, 0x63, 0x6b, 0x5f, 0x69,
+ 0x64, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x03, 0x52, 0x07, 0x72, 0x61, 0x63, 0x6b, 0x49, 0x64,
+ 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x5f, 0x76, 0x65,
+ 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x66, 0x69,
+ 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x18,
+ 0x0a, 0x05, 0x7a, 0x6f, 0x6e, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x42, 0x02, 0x18,
+ 0x01, 0x52, 0x05, 0x7a, 0x6f, 0x6e, 0x65, 0x73, 0x12, 0x4d, 0x0a, 0x0e, 0x6e, 0x75, 0x6d, 0x65,
+ 0x72, 0x69, 0x63, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b,
+ 0x32, 0x26, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65,
+ 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x52, 0x61, 0x6e,
+ 0x67, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x0d, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69,
+ 0x63, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x70, 0x5f, 0x63, 0x69,
+ 0x64, 0x72, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x69, 0x70, 0x43, 0x69, 0x64,
+ 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x69, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x0d,
+ 0x20, 0x03, 0x28, 0x03, 0x52, 0x07, 0x73, 0x69, 0x74, 0x65, 0x49, 0x64, 0x73, 0x12, 0x2d, 0x0a,
+ 0x12, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x75, 0x6e, 0x61, 0x73, 0x73, 0x69, 0x67,
+ 0x6e, 0x65, 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x69, 0x6e, 0x63, 0x6c, 0x75,
+ 0x64, 0x65, 0x55, 0x6e, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c,
+ 0x62, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x0f, 0x20, 0x03,
+ 0x28, 0x03, 0x52, 0x0b, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x64, 0x73, 0x12,
+ 0x2e, 0x0a, 0x13, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x6e, 0x6f, 0x5f, 0x62, 0x75,
+ 0x69, 0x6c, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x69, 0x6e,
+ 0x63, 0x6c, 0x75, 0x64, 0x65, 0x4e, 0x6f, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x6e, 0x67, 0x12,
+ 0x2f, 0x0a, 0x09, 0x7a, 0x6f, 0x6e, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x11, 0x20, 0x03,
+ 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x5a,
+ 0x6f, 0x6e, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x08, 0x7a, 0x6f, 0x6e, 0x65, 0x4b, 0x65, 0x79, 0x73,
+ 0x12, 0x26, 0x0a, 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x6e, 0x6f, 0x5f, 0x72,
+ 0x61, 0x63, 0x6b, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x69, 0x6e, 0x63, 0x6c, 0x75,
+ 0x64, 0x65, 0x4e, 0x6f, 0x52, 0x61, 0x63, 0x6b, 0x22, 0xf6, 0x01, 0x0a, 0x12, 0x4e, 0x75, 0x6d,
+ 0x65, 0x72, 0x69, 0x63, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12,
+ 0x36, 0x0a, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20,
+ 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74,
+ 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x46, 0x69, 0x65, 0x6c, 0x64,
+ 0x52, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x2e, 0x0a, 0x03, 0x6d, 0x69, 0x6e, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c,
+ 0x75, 0x65, 0x52, 0x03, 0x6d, 0x69, 0x6e, 0x12, 0x2e, 0x0a, 0x03, 0x6d, 0x61, 0x78, 0x18, 0x03,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c,
+ 0x75, 0x65, 0x52, 0x03, 0x6d, 0x61, 0x78, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x69, 0x6e, 0x5f, 0x69,
+ 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c,
+ 0x6d, 0x69, 0x6e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x12, 0x23, 0x0a, 0x0d,
+ 0x6d, 0x61, 0x78, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x18, 0x05, 0x20,
+ 0x01, 0x28, 0x08, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76,
+ 0x65, 0x22, 0xaf, 0x02, 0x0a, 0x1f, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x53,
+ 0x74, 0x61, 0x74, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x52, 0x65, 0x73,
+ 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x06, 0x6d, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18,
+ 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e,
0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x69, 0x6e, 0x65, 0x72,
- 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x06, 0x67, 0x72, 0x6f, 0x75,
- 0x70, 0x73, 0x22, 0x51, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x43, 0x6f,
- 0x6f, 0x6c, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
- 0x12, 0x33, 0x0a, 0x11, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74,
- 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xba, 0x48, 0x03,
- 0xc8, 0x01, 0x01, 0x52, 0x10, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74,
- 0x69, 0x66, 0x69, 0x65, 0x72, 0x22, 0x58, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x65,
- 0x72, 0x43, 0x6f, 0x6f, 0x6c, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70,
- 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x0c, 0x63, 0x6f, 0x6f, 0x6c, 0x69, 0x6e, 0x67, 0x5f,
- 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x63, 0x6f, 0x6d,
- 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6f, 0x6c, 0x69, 0x6e, 0x67, 0x4d, 0x6f,
- 0x64, 0x65, 0x52, 0x0b, 0x63, 0x6f, 0x6f, 0x6c, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x22,
- 0xb6, 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74,
- 0x6f, 0x72, 0x12, 0x46, 0x0a, 0x0b, 0x61, 0x6c, 0x6c, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65,
- 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d,
+ 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x06, 0x6d,
+ 0x69, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x18,
+ 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x12, 0x21, 0x0a,
+ 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x6d, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20,
+ 0x01, 0x28, 0x05, 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x73,
+ 0x12, 0x4c, 0x0a, 0x12, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f,
+ 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74,
+ 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x69, 0x6e, 0x65,
+ 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x10, 0x74, 0x6f,
+ 0x74, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x16,
+ 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06,
+ 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61,
+ 0x72, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28,
+ 0x09, 0x52, 0x10, 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69,
+ 0x6f, 0x6e, 0x73, 0x22, 0x35, 0x0a, 0x14, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x4d, 0x69,
+ 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x64,
+ 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52,
+ 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x73, 0x22, 0xe7, 0x01, 0x0a, 0x15, 0x52,
+ 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70,
+ 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x09, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74,
+ 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d,
0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x69, 0x6e,
- 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, 0x0a,
- 0x61, 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x4a, 0x0a, 0x0f, 0x69, 0x6e,
- 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20,
- 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e,
- 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72,
- 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x44,
- 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x42, 0x10, 0x0a, 0x0e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74,
- 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x22, 0x62, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65,
- 0x74, 0x65, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
- 0x4b, 0x0a, 0x0f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74,
- 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74,
- 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65,
- 0x76, 0x69, 0x63, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x0e, 0x64, 0x65,
- 0x76, 0x69, 0x63, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x22, 0x3b, 0x0a, 0x14,
- 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70,
- 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x5f,
- 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x64, 0x65, 0x6c,
- 0x65, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xe3, 0x01, 0x0a, 0x13, 0x52, 0x65,
- 0x6e, 0x61, 0x6d, 0x65, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
- 0x74, 0x12, 0x53, 0x0a, 0x0f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x73, 0x65, 0x6c, 0x65,
- 0x63, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x66, 0x6c, 0x65,
+ 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52,
+ 0x09, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x12, 0x4d, 0x0a, 0x06, 0x65, 0x72,
+ 0x72, 0x6f, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x66, 0x6c, 0x65,
0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e,
- 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x42, 0x06,
- 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x65,
- 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x4c, 0x0a, 0x0b, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x63,
- 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x66, 0x6c,
- 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31,
- 0x2e, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
- 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x43, 0x6f,
- 0x6e, 0x66, 0x69, 0x67, 0x12, 0x29, 0x0a, 0x04, 0x73, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x03,
- 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53,
- 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x04, 0x73, 0x6f, 0x72, 0x74, 0x22,
- 0x87, 0x01, 0x0a, 0x14, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x73,
- 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x6e, 0x61,
- 0x6d, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52,
- 0x0c, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x27, 0x0a,
- 0x0f, 0x75, 0x6e, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74,
- 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x75, 0x6e, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65,
- 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64,
- 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x66, 0x61,
- 0x69, 0x6c, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xc4, 0x02, 0x0a, 0x18, 0x55, 0x70,
- 0x64, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52,
- 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x53, 0x0a, 0x0f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65,
- 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
- 0x22, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e,
- 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63,
- 0x74, 0x6f, 0x72, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0e, 0x64, 0x65, 0x76,
- 0x69, 0x63, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x4c, 0x0a, 0x0b, 0x6e,
- 0x61, 0x6d, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
- 0x32, 0x23, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65,
- 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x43,
- 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0a, 0x6e,
- 0x61, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x29, 0x0a, 0x04, 0x73, 0x6f, 0x72,
- 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
- 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x04,
- 0x73, 0x6f, 0x72, 0x74, 0x12, 0x2c, 0x0a, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x75, 0x73, 0x65,
- 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04,
- 0x72, 0x02, 0x10, 0x01, 0x52, 0x0c, 0x75, 0x73, 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61,
- 0x6d, 0x65, 0x12, 0x2c, 0x0a, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77,
- 0x6f, 0x72, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02,
- 0x10, 0x01, 0x52, 0x0c, 0x75, 0x73, 0x65, 0x72, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64,
- 0x22, 0xb7, 0x01, 0x0a, 0x19, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x65,
- 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23,
- 0x0a, 0x0d, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18,
- 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x43, 0x6f,
- 0x75, 0x6e, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x75, 0x6e, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64,
- 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x75, 0x6e,
- 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x0c,
- 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01,
- 0x28, 0x05, 0x52, 0x0b, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12,
- 0x29, 0x0a, 0x10, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66,
- 0x69, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x62, 0x61, 0x74, 0x63, 0x68,
- 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x22, 0x8d, 0x01, 0x0a, 0x0f, 0x4d,
- 0x69, 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4a,
- 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03,
- 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65,
- 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70,
- 0x65, 0x72, 0x74, 0x79, 0x42, 0x08, 0xba, 0x48, 0x05, 0x92, 0x01, 0x02, 0x08, 0x01, 0x52, 0x0a,
- 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x09, 0x73, 0x65,
- 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x10, 0xba,
- 0x48, 0x0d, 0x72, 0x0b, 0x52, 0x01, 0x2d, 0x52, 0x01, 0x5f, 0x52, 0x01, 0x2e, 0x52, 0x00, 0x52,
- 0x09, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x22, 0x90, 0x03, 0x0a, 0x0c, 0x4e,
- 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x12, 0x5c, 0x0a, 0x12, 0x73,
- 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65,
- 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d,
- 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72,
- 0x69, 0x6e, 0x67, 0x41, 0x6e, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f,
- 0x70, 0x65, 0x72, 0x74, 0x79, 0x48, 0x00, 0x52, 0x10, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x41,
- 0x6e, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x3f, 0x0a, 0x07, 0x63, 0x6f, 0x75,
- 0x6e, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x66, 0x6c, 0x65,
+ 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73,
+ 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72,
+ 0x79, 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x45, 0x72, 0x72,
+ 0x6f, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61,
+ 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
+ 0x3a, 0x02, 0x38, 0x01, 0x22, 0xab, 0x01, 0x0a, 0x19, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x4d,
+ 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x73, 0x76, 0x52, 0x65, 0x71, 0x75, 0x65,
+ 0x73, 0x74, 0x12, 0x3b, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65,
+ 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x69, 0x73,
+ 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12,
+ 0x51, 0x0a, 0x10, 0x74, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x75,
+ 0x6e, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x66, 0x6c, 0x65, 0x65,
+ 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43,
+ 0x73, 0x76, 0x54, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x55, 0x6e, 0x69,
+ 0x74, 0x52, 0x0f, 0x74, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x55, 0x6e,
+ 0x69, 0x74, 0x22, 0x37, 0x0a, 0x1a, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x4d, 0x69, 0x6e, 0x65,
+ 0x72, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x73, 0x76, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+ 0x12, 0x19, 0x0a, 0x08, 0x63, 0x73, 0x76, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x0c, 0x52, 0x07, 0x63, 0x73, 0x76, 0x44, 0x61, 0x74, 0x61, 0x22, 0x66, 0x0a, 0x1a, 0x47,
+ 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x75, 0x6e,
+ 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x69, 0x74,
+ 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x03, 0x52, 0x07, 0x73, 0x69, 0x74,
+ 0x65, 0x49, 0x64, 0x73, 0x12, 0x2d, 0x0a, 0x12, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f,
+ 0x75, 0x6e, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08,
+ 0x52, 0x11, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x55, 0x6e, 0x61, 0x73, 0x73, 0x69, 0x67,
+ 0x6e, 0x65, 0x64, 0x22, 0x83, 0x01, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72,
+ 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
+ 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x6d, 0x69, 0x6e,
+ 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c,
+ 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x41, 0x0a, 0x0c, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f,
+ 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74,
+ 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x69, 0x6e, 0x65,
+ 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x0b, 0x73, 0x74,
+ 0x61, 0x74, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x22, 0x55, 0x0a, 0x1e, 0x47, 0x65, 0x74,
+ 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x50, 0x6f, 0x6f, 0x6c, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d,
+ 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x33, 0x0a, 0x11, 0x64,
+ 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x10,
+ 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72,
+ 0x22, 0x68, 0x0a, 0x0e, 0x50, 0x6f, 0x6f, 0x6c, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65,
+ 0x6e, 0x74, 0x12, 0x1c, 0x0a, 0x07, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x06, 0x70, 0x6f, 0x6f, 0x6c, 0x49, 0x64, 0x88, 0x01, 0x01,
+ 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75,
+ 0x72, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x0a,
+ 0x0a, 0x08, 0x5f, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x69, 0x64, 0x22, 0x5b, 0x0a, 0x1f, 0x47, 0x65,
+ 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x50, 0x6f, 0x6f, 0x6c, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e,
+ 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a,
+ 0x05, 0x70, 0x6f, 0x6f, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x66,
+ 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76,
+ 0x31, 0x2e, 0x50, 0x6f, 0x6f, 0x6c, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74,
+ 0x52, 0x05, 0x70, 0x6f, 0x6f, 0x6c, 0x73, 0x22, 0x61, 0x0a, 0x0f, 0x4d, 0x69, 0x6e, 0x65, 0x72,
+ 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f,
+ 0x64, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c,
+ 0x12, 0x22, 0x0a, 0x0c, 0x6d, 0x61, 0x6e, 0x75, 0x66, 0x61, 0x63, 0x74, 0x75, 0x72, 0x65, 0x72,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6d, 0x61, 0x6e, 0x75, 0x66, 0x61, 0x63, 0x74,
+ 0x75, 0x72, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20,
+ 0x01, 0x28, 0x05, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x59, 0x0a, 0x1a, 0x47, 0x65,
+ 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x47, 0x72, 0x6f, 0x75, 0x70,
+ 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3b, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74,
+ 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74,
+ 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x69,
+ 0x6e, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66,
+ 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x5a, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x65,
+ 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70,
+ 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x01,
+ 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61,
+ 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x4d,
+ 0x6f, 0x64, 0x65, 0x6c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70,
+ 0x73, 0x22, 0x51, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6f,
+ 0x6c, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+ 0x33, 0x0a, 0x11, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69,
+ 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8,
+ 0x01, 0x01, 0x52, 0x10, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69,
+ 0x66, 0x69, 0x65, 0x72, 0x22, 0x58, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72,
+ 0x43, 0x6f, 0x6f, 0x6c, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f,
+ 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x0c, 0x63, 0x6f, 0x6f, 0x6c, 0x69, 0x6e, 0x67, 0x5f, 0x6d,
+ 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x63, 0x6f, 0x6d, 0x6d,
+ 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6f, 0x6c, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64,
+ 0x65, 0x52, 0x0b, 0x63, 0x6f, 0x6f, 0x6c, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x22, 0xb6,
+ 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f,
+ 0x72, 0x12, 0x46, 0x0a, 0x0b, 0x61, 0x6c, 0x6c, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61,
+ 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x69, 0x6e, 0x65,
+ 0x72, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, 0x0a, 0x61,
+ 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x4a, 0x0a, 0x0f, 0x69, 0x6e, 0x63,
+ 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x44,
+ 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x4c,
+ 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x44, 0x65,
+ 0x76, 0x69, 0x63, 0x65, 0x73, 0x42, 0x10, 0x0a, 0x0e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69,
+ 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x22, 0x62, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74,
+ 0x65, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4b,
+ 0x0a, 0x0f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f,
+ 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d,
+ 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76,
+ 0x69, 0x63, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x0e, 0x64, 0x65, 0x76,
+ 0x69, 0x63, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x22, 0x3b, 0x0a, 0x14, 0x44,
+ 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
+ 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x63,
+ 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x64, 0x65, 0x6c, 0x65,
+ 0x74, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xe3, 0x01, 0x0a, 0x13, 0x52, 0x65, 0x6e,
+ 0x61, 0x6d, 0x65, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+ 0x12, 0x53, 0x0a, 0x0f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63,
+ 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x66, 0x6c, 0x65, 0x65,
+ 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44,
+ 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x42, 0x06, 0xba,
+ 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x65, 0x6c,
+ 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x4c, 0x0a, 0x0b, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x63, 0x6f,
+ 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x66, 0x6c, 0x65,
0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e,
- 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x48,
- 0x00, 0x52, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x47, 0x0a, 0x0c, 0x73, 0x74,
- 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b,
- 0x32, 0x22, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65,
- 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x70,
- 0x65, 0x72, 0x74, 0x79, 0x48, 0x00, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61,
- 0x6c, 0x75, 0x65, 0x12, 0x49, 0x0a, 0x0b, 0x66, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x76, 0x61, 0x6c,
- 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74,
- 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69,
- 0x78, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79,
- 0x48, 0x00, 0x52, 0x0a, 0x66, 0x69, 0x78, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x45,
- 0x0a, 0x09, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28,
- 0x0b, 0x32, 0x25, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d,
- 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x61, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x72,
- 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x48, 0x00, 0x52, 0x09, 0x71, 0x75, 0x61, 0x6c,
- 0x69, 0x66, 0x69, 0x65, 0x72, 0x42, 0x06, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x22, 0xa8, 0x01,
- 0x0a, 0x18, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x41, 0x6e, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74,
- 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72,
- 0x65, 0x66, 0x69, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x72, 0x65, 0x66,
- 0x69, 0x78, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x75, 0x66, 0x66, 0x69, 0x78, 0x18, 0x02, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x06, 0x73, 0x75, 0x66, 0x66, 0x69, 0x78, 0x12, 0x2c, 0x0a, 0x0d, 0x63, 0x6f,
- 0x75, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28,
+ 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42,
+ 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x43, 0x6f, 0x6e,
+ 0x66, 0x69, 0x67, 0x12, 0x29, 0x0a, 0x04, 0x73, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28,
+ 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x6f,
+ 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x04, 0x73, 0x6f, 0x72, 0x74, 0x22, 0x87,
+ 0x01, 0x0a, 0x14, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52,
+ 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x6e, 0x61, 0x6d,
+ 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c,
+ 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x27, 0x0a, 0x0f,
+ 0x75, 0x6e, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18,
+ 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x75, 0x6e, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64,
+ 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x5f,
+ 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x66, 0x61, 0x69,
+ 0x6c, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xc4, 0x02, 0x0a, 0x18, 0x55, 0x70, 0x64,
+ 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65,
+ 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x53, 0x0a, 0x0f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f,
+ 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22,
+ 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74,
+ 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74,
+ 0x6f, 0x72, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0e, 0x64, 0x65, 0x76, 0x69,
+ 0x63, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x4c, 0x0a, 0x0b, 0x6e, 0x61,
+ 0x6d, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x23, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e,
+ 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x43, 0x6f,
+ 0x6e, 0x66, 0x69, 0x67, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0a, 0x6e, 0x61,
+ 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x29, 0x0a, 0x04, 0x73, 0x6f, 0x72, 0x74,
+ 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e,
+ 0x76, 0x31, 0x2e, 0x53, 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x04, 0x73,
+ 0x6f, 0x72, 0x74, 0x12, 0x2c, 0x0a, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x75, 0x73, 0x65, 0x72,
+ 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72,
+ 0x02, 0x10, 0x01, 0x52, 0x0c, 0x75, 0x73, 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d,
+ 0x65, 0x12, 0x2c, 0x0a, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f,
+ 0x72, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10,
+ 0x01, 0x52, 0x0c, 0x75, 0x73, 0x65, 0x72, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22,
+ 0xb7, 0x01, 0x0a, 0x19, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72,
+ 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a,
+ 0x0d, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x75,
+ 0x6e, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x75, 0x6e, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x5f,
+ 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x75, 0x6e, 0x63,
+ 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x66,
+ 0x61, 0x69, 0x6c, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28,
+ 0x05, 0x52, 0x0b, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x29,
+ 0x0a, 0x10, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69,
+ 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x49,
+ 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x22, 0x8d, 0x01, 0x0a, 0x0f, 0x4d, 0x69,
+ 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4a, 0x0a,
+ 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
+ 0x0b, 0x32, 0x20, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d,
+ 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65,
+ 0x72, 0x74, 0x79, 0x42, 0x08, 0xba, 0x48, 0x05, 0x92, 0x01, 0x02, 0x08, 0x01, 0x52, 0x0a, 0x70,
+ 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x09, 0x73, 0x65, 0x70,
+ 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x10, 0xba, 0x48,
+ 0x0d, 0x72, 0x0b, 0x52, 0x01, 0x2d, 0x52, 0x01, 0x5f, 0x52, 0x01, 0x2e, 0x52, 0x00, 0x52, 0x09,
+ 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x22, 0x90, 0x03, 0x0a, 0x0c, 0x4e, 0x61,
+ 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x12, 0x5c, 0x0a, 0x12, 0x73, 0x74,
+ 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61,
+ 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x69,
+ 0x6e, 0x67, 0x41, 0x6e, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70,
+ 0x65, 0x72, 0x74, 0x79, 0x48, 0x00, 0x52, 0x10, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x41, 0x6e,
+ 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x3f, 0x0a, 0x07, 0x63, 0x6f, 0x75, 0x6e,
+ 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x66, 0x6c, 0x65, 0x65,
+ 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43,
+ 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x48, 0x00,
+ 0x52, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x47, 0x0a, 0x0c, 0x73, 0x74, 0x72,
+ 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x22, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e,
+ 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x70, 0x65,
+ 0x72, 0x74, 0x79, 0x48, 0x00, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c,
+ 0x75, 0x65, 0x12, 0x49, 0x0a, 0x0b, 0x66, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x75,
+ 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d,
+ 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x78,
+ 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x48,
+ 0x00, 0x52, 0x0a, 0x66, 0x69, 0x78, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x45, 0x0a,
+ 0x09, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x25, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65,
+ 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x61, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x72, 0x50,
+ 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x48, 0x00, 0x52, 0x09, 0x71, 0x75, 0x61, 0x6c, 0x69,
+ 0x66, 0x69, 0x65, 0x72, 0x42, 0x06, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x22, 0xa8, 0x01, 0x0a,
+ 0x18, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x41, 0x6e, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65,
+ 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, 0x65,
+ 0x66, 0x69, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69,
+ 0x78, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x75, 0x66, 0x66, 0x69, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x06, 0x73, 0x75, 0x66, 0x66, 0x69, 0x78, 0x12, 0x2c, 0x0a, 0x0d, 0x63, 0x6f, 0x75,
+ 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05,
+ 0x42, 0x07, 0xba, 0x48, 0x04, 0x1a, 0x02, 0x28, 0x00, 0x52, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74,
+ 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x2e, 0x0a, 0x0d, 0x63, 0x6f, 0x75, 0x6e, 0x74,
+ 0x65, 0x72, 0x5f, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x42, 0x09,
+ 0xba, 0x48, 0x06, 0x1a, 0x04, 0x18, 0x06, 0x28, 0x01, 0x52, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74,
+ 0x65, 0x72, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x22, 0x6f, 0x0a, 0x0f, 0x43, 0x6f, 0x75, 0x6e, 0x74,
+ 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x12, 0x2c, 0x0a, 0x0d, 0x63, 0x6f,
+ 0x75, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28,
0x05, 0x42, 0x07, 0xba, 0x48, 0x04, 0x1a, 0x02, 0x28, 0x00, 0x52, 0x0c, 0x63, 0x6f, 0x75, 0x6e,
0x74, 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x2e, 0x0a, 0x0d, 0x63, 0x6f, 0x75, 0x6e,
- 0x74, 0x65, 0x72, 0x5f, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x42,
+ 0x74, 0x65, 0x72, 0x5f, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x42,
0x09, 0xba, 0x48, 0x06, 0x1a, 0x04, 0x18, 0x06, 0x28, 0x01, 0x52, 0x0c, 0x63, 0x6f, 0x75, 0x6e,
- 0x74, 0x65, 0x72, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x22, 0x6f, 0x0a, 0x0f, 0x43, 0x6f, 0x75, 0x6e,
- 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x12, 0x2c, 0x0a, 0x0d, 0x63,
- 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x05, 0x42, 0x07, 0xba, 0x48, 0x04, 0x1a, 0x02, 0x28, 0x00, 0x52, 0x0c, 0x63, 0x6f, 0x75,
- 0x6e, 0x74, 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x2e, 0x0a, 0x0d, 0x63, 0x6f, 0x75,
- 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05,
- 0x42, 0x09, 0xba, 0x48, 0x06, 0x1a, 0x04, 0x18, 0x06, 0x28, 0x01, 0x52, 0x0c, 0x63, 0x6f, 0x75,
- 0x6e, 0x74, 0x65, 0x72, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x22, 0x2f, 0x0a, 0x0e, 0x53, 0x74, 0x72,
- 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x12, 0x1d, 0x0a, 0x05, 0x76,
- 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72,
- 0x02, 0x10, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x91, 0x03, 0x0a, 0x12, 0x46,
- 0x69, 0x78, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74,
- 0x79, 0x12, 0x40, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32,
- 0x22, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e,
- 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x78, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x54,
- 0x79, 0x70, 0x65, 0x42, 0x08, 0xba, 0x48, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x04, 0x74,
- 0x79, 0x70, 0x65, 0x12, 0x37, 0x0a, 0x0f, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72,
- 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x42, 0x09, 0xba, 0x48,
- 0x06, 0x1a, 0x04, 0x18, 0x06, 0x28, 0x01, 0x48, 0x00, 0x52, 0x0e, 0x63, 0x68, 0x61, 0x72, 0x61,
- 0x63, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x12, 0x4d, 0x0a, 0x07,
- 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e,
- 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e,
- 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x53, 0x65, 0x63, 0x74,
- 0x69, 0x6f, 0x6e, 0x42, 0x08, 0xba, 0x48, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x48, 0x01, 0x52,
- 0x07, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x3a, 0x90, 0x01, 0xba, 0x48,
- 0x8c, 0x01, 0x1a, 0x89, 0x01, 0x0a, 0x25, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72,
- 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x63, 0x68, 0x61,
- 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2f, 0x73, 0x65,
- 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65,
- 0x64, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72,
- 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x69, 0x73, 0x20, 0x73, 0x65, 0x74, 0x1a, 0x2f, 0x21,
- 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74,
- 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x68, 0x61, 0x73,
- 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x42, 0x12,
- 0x0a, 0x10, 0x5f, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x75,
- 0x6e, 0x74, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x84,
- 0x01, 0x0a, 0x11, 0x51, 0x75, 0x61, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70,
- 0x65, 0x72, 0x74, 0x79, 0x12, 0x3f, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65,
- 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x61, 0x6c, 0x69, 0x66, 0x69, 0x65,
- 0x72, 0x54, 0x79, 0x70, 0x65, 0x42, 0x08, 0xba, 0x48, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52,
- 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18,
- 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x16, 0x0a,
- 0x06, 0x73, 0x75, 0x66, 0x66, 0x69, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73,
- 0x75, 0x66, 0x66, 0x69, 0x78, 0x2a, 0x99, 0x01, 0x0a, 0x1f, 0x46, 0x6c, 0x65, 0x65, 0x74, 0x4d,
- 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
- 0x45, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x33, 0x0a, 0x2f, 0x46, 0x4c, 0x45,
- 0x45, 0x54, 0x5f, 0x4d, 0x41, 0x4e, 0x41, 0x47, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x45,
- 0x52, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x4f, 0x44, 0x45,
- 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x41,
- 0x0a, 0x3d, 0x46, 0x4c, 0x45, 0x45, 0x54, 0x5f, 0x4d, 0x41, 0x4e, 0x41, 0x47, 0x45, 0x4d, 0x45,
- 0x4e, 0x54, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52,
- 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x50, 0x41,
- 0x47, 0x49, 0x4e, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x55, 0x52, 0x53, 0x4f, 0x52, 0x10,
- 0x01, 0x2a, 0x9a, 0x02, 0x0a, 0x0c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74,
- 0x75, 0x73, 0x12, 0x1d, 0x0a, 0x19, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x53, 0x54, 0x41,
- 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10,
- 0x00, 0x12, 0x18, 0x0a, 0x14, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54,
- 0x55, 0x53, 0x5f, 0x4f, 0x4e, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x44,
- 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4f, 0x46, 0x46,
- 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x02, 0x12, 0x1d, 0x0a, 0x19, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45,
- 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x54, 0x45, 0x4e, 0x41,
- 0x4e, 0x43, 0x45, 0x10, 0x03, 0x12, 0x17, 0x0a, 0x13, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f,
- 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x04, 0x12, 0x1a,
- 0x0a, 0x16, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f,
- 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x05, 0x12, 0x23, 0x0a, 0x1f, 0x44, 0x45,
- 0x56, 0x49, 0x43, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4e, 0x45, 0x45, 0x44,
- 0x53, 0x5f, 0x4d, 0x49, 0x4e, 0x49, 0x4e, 0x47, 0x5f, 0x50, 0x4f, 0x4f, 0x4c, 0x10, 0x06, 0x12,
- 0x1a, 0x0a, 0x16, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53,
- 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x07, 0x12, 0x21, 0x0a, 0x1d, 0x44,
- 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, 0x42,
- 0x4f, 0x4f, 0x54, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x49, 0x52, 0x45, 0x44, 0x10, 0x08, 0x2a, 0xed,
- 0x01, 0x0a, 0x0d, 0x50, 0x61, 0x69, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
- 0x12, 0x1e, 0x0a, 0x1a, 0x50, 0x41, 0x49, 0x52, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x54, 0x41, 0x54,
- 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00,
- 0x12, 0x19, 0x0a, 0x15, 0x50, 0x41, 0x49, 0x52, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x54, 0x41, 0x54,
- 0x55, 0x53, 0x5f, 0x50, 0x41, 0x49, 0x52, 0x45, 0x44, 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, 0x50,
- 0x41, 0x49, 0x52, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e,
- 0x50, 0x41, 0x49, 0x52, 0x45, 0x44, 0x10, 0x02, 0x12, 0x28, 0x0a, 0x24, 0x50, 0x41, 0x49, 0x52,
- 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x41, 0x55, 0x54, 0x48, 0x45,
- 0x4e, 0x54, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x45, 0x45, 0x44, 0x45, 0x44,
- 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x50, 0x41, 0x49, 0x52, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x54,
- 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x04, 0x12, 0x19,
- 0x0a, 0x15, 0x50, 0x41, 0x49, 0x52, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53,
- 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x05, 0x12, 0x23, 0x0a, 0x1f, 0x50, 0x41, 0x49,
- 0x52, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x44, 0x45, 0x46, 0x41,
- 0x55, 0x4c, 0x54, 0x5f, 0x50, 0x41, 0x53, 0x53, 0x57, 0x4f, 0x52, 0x44, 0x10, 0x06, 0x2a, 0xe6,
- 0x01, 0x0a, 0x0c, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12,
- 0x1d, 0x0a, 0x19, 0x4e, 0x55, 0x4d, 0x45, 0x52, 0x49, 0x43, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44,
- 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1e,
- 0x0a, 0x1a, 0x4e, 0x55, 0x4d, 0x45, 0x52, 0x49, 0x43, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f,
- 0x48, 0x41, 0x53, 0x48, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x54, 0x48, 0x53, 0x10, 0x01, 0x12, 0x20,
- 0x0a, 0x1c, 0x4e, 0x55, 0x4d, 0x45, 0x52, 0x49, 0x43, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f,
- 0x45, 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x4a, 0x54, 0x48, 0x10, 0x02,
- 0x12, 0x1a, 0x0a, 0x16, 0x4e, 0x55, 0x4d, 0x45, 0x52, 0x49, 0x43, 0x5f, 0x46, 0x49, 0x45, 0x4c,
- 0x44, 0x5f, 0x50, 0x4f, 0x57, 0x45, 0x52, 0x5f, 0x4b, 0x57, 0x10, 0x03, 0x12, 0x1f, 0x0a, 0x1b,
- 0x4e, 0x55, 0x4d, 0x45, 0x52, 0x49, 0x43, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x54, 0x45,
- 0x4d, 0x50, 0x45, 0x52, 0x41, 0x54, 0x55, 0x52, 0x45, 0x5f, 0x43, 0x10, 0x04, 0x12, 0x1b, 0x0a,
- 0x17, 0x4e, 0x55, 0x4d, 0x45, 0x52, 0x49, 0x43, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x56,
- 0x4f, 0x4c, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x56, 0x10, 0x05, 0x12, 0x1b, 0x0a, 0x17, 0x4e, 0x55,
- 0x4d, 0x45, 0x52, 0x49, 0x43, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x43, 0x55, 0x52, 0x52,
- 0x45, 0x4e, 0x54, 0x5f, 0x41, 0x10, 0x06, 0x2a, 0x81, 0x01, 0x0a, 0x12, 0x43, 0x73, 0x76, 0x54,
- 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x55, 0x6e, 0x69, 0x74, 0x12, 0x24,
- 0x0a, 0x20, 0x43, 0x53, 0x56, 0x5f, 0x54, 0x45, 0x4d, 0x50, 0x45, 0x52, 0x41, 0x54, 0x55, 0x52,
- 0x45, 0x5f, 0x55, 0x4e, 0x49, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49,
- 0x45, 0x44, 0x10, 0x00, 0x12, 0x20, 0x0a, 0x1c, 0x43, 0x53, 0x56, 0x5f, 0x54, 0x45, 0x4d, 0x50,
- 0x45, 0x52, 0x41, 0x54, 0x55, 0x52, 0x45, 0x5f, 0x55, 0x4e, 0x49, 0x54, 0x5f, 0x43, 0x45, 0x4c,
- 0x53, 0x49, 0x55, 0x53, 0x10, 0x01, 0x12, 0x23, 0x0a, 0x1f, 0x43, 0x53, 0x56, 0x5f, 0x54, 0x45,
- 0x4d, 0x50, 0x45, 0x52, 0x41, 0x54, 0x55, 0x52, 0x45, 0x5f, 0x55, 0x4e, 0x49, 0x54, 0x5f, 0x46,
- 0x41, 0x48, 0x52, 0x45, 0x4e, 0x48, 0x45, 0x49, 0x54, 0x10, 0x02, 0x2a, 0x99, 0x02, 0x0a, 0x0e,
- 0x46, 0x69, 0x78, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x20,
- 0x0a, 0x1c, 0x46, 0x49, 0x58, 0x45, 0x44, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x54, 0x59,
- 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00,
- 0x12, 0x20, 0x0a, 0x1c, 0x46, 0x49, 0x58, 0x45, 0x44, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f,
- 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x41, 0x43, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53,
- 0x10, 0x01, 0x12, 0x22, 0x0a, 0x1e, 0x46, 0x49, 0x58, 0x45, 0x44, 0x5f, 0x56, 0x41, 0x4c, 0x55,
- 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x45, 0x52, 0x49, 0x41, 0x4c, 0x5f, 0x4e, 0x55,
- 0x4d, 0x42, 0x45, 0x52, 0x10, 0x02, 0x12, 0x20, 0x0a, 0x1c, 0x46, 0x49, 0x58, 0x45, 0x44, 0x5f,
- 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x57, 0x4f, 0x52, 0x4b, 0x45,
- 0x52, 0x5f, 0x4e, 0x41, 0x4d, 0x45, 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x46, 0x49, 0x58, 0x45,
- 0x44, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x4f, 0x44,
- 0x45, 0x4c, 0x10, 0x04, 0x12, 0x21, 0x0a, 0x1d, 0x46, 0x49, 0x58, 0x45, 0x44, 0x5f, 0x56, 0x41,
- 0x4c, 0x55, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x41, 0x4e, 0x55, 0x46, 0x41, 0x43,
- 0x54, 0x55, 0x52, 0x45, 0x52, 0x10, 0x05, 0x12, 0x1d, 0x0a, 0x19, 0x46, 0x49, 0x58, 0x45, 0x44,
- 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4c, 0x4f, 0x43, 0x41,
- 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x06, 0x12, 0x1f, 0x0a, 0x1b, 0x46, 0x49, 0x58, 0x45, 0x44, 0x5f,
- 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x49, 0x4e, 0x45, 0x52,
- 0x5f, 0x4e, 0x41, 0x4d, 0x45, 0x10, 0x07, 0x2a, 0x6e, 0x0a, 0x10, 0x43, 0x68, 0x61, 0x72, 0x61,
- 0x63, 0x74, 0x65, 0x72, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x1d, 0x43,
- 0x48, 0x41, 0x52, 0x41, 0x43, 0x54, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e,
- 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1b,
- 0x0a, 0x17, 0x43, 0x48, 0x41, 0x52, 0x41, 0x43, 0x54, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x43, 0x54,
- 0x49, 0x4f, 0x4e, 0x5f, 0x46, 0x49, 0x52, 0x53, 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x43,
- 0x48, 0x41, 0x52, 0x41, 0x43, 0x54, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e,
- 0x5f, 0x4c, 0x41, 0x53, 0x54, 0x10, 0x02, 0x2a, 0x87, 0x01, 0x0a, 0x0d, 0x51, 0x75, 0x61, 0x6c,
- 0x69, 0x66, 0x69, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1e, 0x0a, 0x1a, 0x51, 0x55, 0x41,
- 0x4c, 0x49, 0x46, 0x49, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50,
- 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x51, 0x55, 0x41,
- 0x4c, 0x49, 0x46, 0x49, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x55, 0x49, 0x4c,
- 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x51, 0x55, 0x41, 0x4c, 0x49, 0x46,
- 0x49, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x52, 0x41, 0x43, 0x4b, 0x10, 0x02, 0x12,
- 0x20, 0x0a, 0x1c, 0x51, 0x55, 0x41, 0x4c, 0x49, 0x46, 0x49, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50,
- 0x45, 0x5f, 0x52, 0x41, 0x43, 0x4b, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x10,
- 0x03, 0x32, 0x9f, 0x09, 0x0a, 0x16, 0x46, 0x6c, 0x65, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67,
- 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x82, 0x01, 0x0a,
- 0x17, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53,
- 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x12, 0x32, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74,
- 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69,
- 0x73, 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x6e, 0x61, 0x70,
- 0x73, 0x68, 0x6f, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x66,
- 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76,
- 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65,
- 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
- 0x65, 0x12, 0x64, 0x0a, 0x0d, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x4d, 0x69, 0x6e, 0x65,
- 0x72, 0x73, 0x12, 0x28, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65,
- 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x4d,
- 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x66,
+ 0x74, 0x65, 0x72, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x22, 0x2f, 0x0a, 0x0e, 0x53, 0x74, 0x72, 0x69,
+ 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x12, 0x1d, 0x0a, 0x05, 0x76, 0x61,
+ 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02,
+ 0x10, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x91, 0x03, 0x0a, 0x12, 0x46, 0x69,
+ 0x78, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79,
+ 0x12, 0x40, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22,
+ 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74,
+ 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x78, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x54, 0x79,
+ 0x70, 0x65, 0x42, 0x08, 0xba, 0x48, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x04, 0x74, 0x79,
+ 0x70, 0x65, 0x12, 0x37, 0x0a, 0x0f, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x5f,
+ 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x42, 0x09, 0xba, 0x48, 0x06,
+ 0x1a, 0x04, 0x18, 0x06, 0x28, 0x01, 0x48, 0x00, 0x52, 0x0e, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63,
+ 0x74, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x12, 0x4d, 0x0a, 0x07, 0x73,
+ 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x66,
0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76,
- 0x31, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52,
- 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x75, 0x0a, 0x12, 0x45, 0x78, 0x70, 0x6f, 0x72,
- 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x73, 0x76, 0x12, 0x2d, 0x2e,
- 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e,
- 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x69,
- 0x73, 0x74, 0x43, 0x73, 0x76, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x66,
+ 0x31, 0x2e, 0x43, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x53, 0x65, 0x63, 0x74, 0x69,
+ 0x6f, 0x6e, 0x42, 0x08, 0xba, 0x48, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x48, 0x01, 0x52, 0x07,
+ 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x3a, 0x90, 0x01, 0xba, 0x48, 0x8c,
+ 0x01, 0x1a, 0x89, 0x01, 0x0a, 0x25, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65,
+ 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x63, 0x68, 0x61, 0x72,
+ 0x61, 0x63, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2f, 0x73, 0x65, 0x63,
+ 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64,
+ 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x5f,
+ 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x69, 0x73, 0x20, 0x73, 0x65, 0x74, 0x1a, 0x2f, 0x21, 0x68,
+ 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65,
+ 0x72, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x68, 0x61, 0x73, 0x28,
+ 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x42, 0x12, 0x0a,
+ 0x10, 0x5f, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x75, 0x6e,
+ 0x74, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x84, 0x01,
+ 0x0a, 0x11, 0x51, 0x75, 0x61, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65,
+ 0x72, 0x74, 0x79, 0x12, 0x3f, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x0e, 0x32, 0x21, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d,
+ 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x61, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x72,
+ 0x54, 0x79, 0x70, 0x65, 0x42, 0x08, 0xba, 0x48, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x04,
+ 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x16, 0x0a, 0x06,
+ 0x73, 0x75, 0x66, 0x66, 0x69, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x75,
+ 0x66, 0x66, 0x69, 0x78, 0x2a, 0x99, 0x01, 0x0a, 0x1f, 0x46, 0x6c, 0x65, 0x65, 0x74, 0x4d, 0x61,
+ 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45,
+ 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x33, 0x0a, 0x2f, 0x46, 0x4c, 0x45, 0x45,
+ 0x54, 0x5f, 0x4d, 0x41, 0x4e, 0x41, 0x47, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x45, 0x52,
+ 0x56, 0x49, 0x43, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f,
+ 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x41, 0x0a,
+ 0x3d, 0x46, 0x4c, 0x45, 0x45, 0x54, 0x5f, 0x4d, 0x41, 0x4e, 0x41, 0x47, 0x45, 0x4d, 0x45, 0x4e,
+ 0x54, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f,
+ 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x50, 0x41, 0x47,
+ 0x49, 0x4e, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x55, 0x52, 0x53, 0x4f, 0x52, 0x10, 0x01,
+ 0x2a, 0x9a, 0x02, 0x0a, 0x0c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75,
+ 0x73, 0x12, 0x1d, 0x0a, 0x19, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54,
+ 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00,
+ 0x12, 0x18, 0x0a, 0x14, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55,
+ 0x53, 0x5f, 0x4f, 0x4e, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x44, 0x45,
+ 0x56, 0x49, 0x43, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4f, 0x46, 0x46, 0x4c,
+ 0x49, 0x4e, 0x45, 0x10, 0x02, 0x12, 0x1d, 0x0a, 0x19, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f,
+ 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x54, 0x45, 0x4e, 0x41, 0x4e,
+ 0x43, 0x45, 0x10, 0x03, 0x12, 0x17, 0x0a, 0x13, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x53,
+ 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x04, 0x12, 0x1a, 0x0a,
+ 0x16, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x49,
+ 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x05, 0x12, 0x23, 0x0a, 0x1f, 0x44, 0x45, 0x56,
+ 0x49, 0x43, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4e, 0x45, 0x45, 0x44, 0x53,
+ 0x5f, 0x4d, 0x49, 0x4e, 0x49, 0x4e, 0x47, 0x5f, 0x50, 0x4f, 0x4f, 0x4c, 0x10, 0x06, 0x12, 0x1a,
+ 0x0a, 0x16, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f,
+ 0x55, 0x50, 0x44, 0x41, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x07, 0x12, 0x21, 0x0a, 0x1d, 0x44, 0x45,
+ 0x56, 0x49, 0x43, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, 0x42, 0x4f,
+ 0x4f, 0x54, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x49, 0x52, 0x45, 0x44, 0x10, 0x08, 0x2a, 0xed, 0x01,
+ 0x0a, 0x0d, 0x50, 0x61, 0x69, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12,
+ 0x1e, 0x0a, 0x1a, 0x50, 0x41, 0x49, 0x52, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55,
+ 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12,
+ 0x19, 0x0a, 0x15, 0x50, 0x41, 0x49, 0x52, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55,
+ 0x53, 0x5f, 0x50, 0x41, 0x49, 0x52, 0x45, 0x44, 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, 0x50, 0x41,
+ 0x49, 0x52, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x50,
+ 0x41, 0x49, 0x52, 0x45, 0x44, 0x10, 0x02, 0x12, 0x28, 0x0a, 0x24, 0x50, 0x41, 0x49, 0x52, 0x49,
+ 0x4e, 0x47, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x41, 0x55, 0x54, 0x48, 0x45, 0x4e,
+ 0x54, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x45, 0x45, 0x44, 0x45, 0x44, 0x10,
+ 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x50, 0x41, 0x49, 0x52, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x54, 0x41,
+ 0x54, 0x55, 0x53, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x04, 0x12, 0x19, 0x0a,
+ 0x15, 0x50, 0x41, 0x49, 0x52, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f,
+ 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x05, 0x12, 0x23, 0x0a, 0x1f, 0x50, 0x41, 0x49, 0x52,
+ 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55,
+ 0x4c, 0x54, 0x5f, 0x50, 0x41, 0x53, 0x53, 0x57, 0x4f, 0x52, 0x44, 0x10, 0x06, 0x2a, 0xe6, 0x01,
+ 0x0a, 0x0c, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x1d,
+ 0x0a, 0x19, 0x4e, 0x55, 0x4d, 0x45, 0x52, 0x49, 0x43, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f,
+ 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1e, 0x0a,
+ 0x1a, 0x4e, 0x55, 0x4d, 0x45, 0x52, 0x49, 0x43, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x48,
+ 0x41, 0x53, 0x48, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x54, 0x48, 0x53, 0x10, 0x01, 0x12, 0x20, 0x0a,
+ 0x1c, 0x4e, 0x55, 0x4d, 0x45, 0x52, 0x49, 0x43, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x45,
+ 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x4a, 0x54, 0x48, 0x10, 0x02, 0x12,
+ 0x1a, 0x0a, 0x16, 0x4e, 0x55, 0x4d, 0x45, 0x52, 0x49, 0x43, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44,
+ 0x5f, 0x50, 0x4f, 0x57, 0x45, 0x52, 0x5f, 0x4b, 0x57, 0x10, 0x03, 0x12, 0x1f, 0x0a, 0x1b, 0x4e,
+ 0x55, 0x4d, 0x45, 0x52, 0x49, 0x43, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x54, 0x45, 0x4d,
+ 0x50, 0x45, 0x52, 0x41, 0x54, 0x55, 0x52, 0x45, 0x5f, 0x43, 0x10, 0x04, 0x12, 0x1b, 0x0a, 0x17,
+ 0x4e, 0x55, 0x4d, 0x45, 0x52, 0x49, 0x43, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x56, 0x4f,
+ 0x4c, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x56, 0x10, 0x05, 0x12, 0x1b, 0x0a, 0x17, 0x4e, 0x55, 0x4d,
+ 0x45, 0x52, 0x49, 0x43, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x43, 0x55, 0x52, 0x52, 0x45,
+ 0x4e, 0x54, 0x5f, 0x41, 0x10, 0x06, 0x2a, 0x81, 0x01, 0x0a, 0x12, 0x43, 0x73, 0x76, 0x54, 0x65,
+ 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x55, 0x6e, 0x69, 0x74, 0x12, 0x24, 0x0a,
+ 0x20, 0x43, 0x53, 0x56, 0x5f, 0x54, 0x45, 0x4d, 0x50, 0x45, 0x52, 0x41, 0x54, 0x55, 0x52, 0x45,
+ 0x5f, 0x55, 0x4e, 0x49, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45,
+ 0x44, 0x10, 0x00, 0x12, 0x20, 0x0a, 0x1c, 0x43, 0x53, 0x56, 0x5f, 0x54, 0x45, 0x4d, 0x50, 0x45,
+ 0x52, 0x41, 0x54, 0x55, 0x52, 0x45, 0x5f, 0x55, 0x4e, 0x49, 0x54, 0x5f, 0x43, 0x45, 0x4c, 0x53,
+ 0x49, 0x55, 0x53, 0x10, 0x01, 0x12, 0x23, 0x0a, 0x1f, 0x43, 0x53, 0x56, 0x5f, 0x54, 0x45, 0x4d,
+ 0x50, 0x45, 0x52, 0x41, 0x54, 0x55, 0x52, 0x45, 0x5f, 0x55, 0x4e, 0x49, 0x54, 0x5f, 0x46, 0x41,
+ 0x48, 0x52, 0x45, 0x4e, 0x48, 0x45, 0x49, 0x54, 0x10, 0x02, 0x2a, 0x99, 0x02, 0x0a, 0x0e, 0x46,
+ 0x69, 0x78, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x20, 0x0a,
+ 0x1c, 0x46, 0x49, 0x58, 0x45, 0x44, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x54, 0x59, 0x50,
+ 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12,
+ 0x20, 0x0a, 0x1c, 0x46, 0x49, 0x58, 0x45, 0x44, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x54,
+ 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x41, 0x43, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x10,
+ 0x01, 0x12, 0x22, 0x0a, 0x1e, 0x46, 0x49, 0x58, 0x45, 0x44, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45,
+ 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x45, 0x52, 0x49, 0x41, 0x4c, 0x5f, 0x4e, 0x55, 0x4d,
+ 0x42, 0x45, 0x52, 0x10, 0x02, 0x12, 0x20, 0x0a, 0x1c, 0x46, 0x49, 0x58, 0x45, 0x44, 0x5f, 0x56,
+ 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x57, 0x4f, 0x52, 0x4b, 0x45, 0x52,
+ 0x5f, 0x4e, 0x41, 0x4d, 0x45, 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x46, 0x49, 0x58, 0x45, 0x44,
+ 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x4f, 0x44, 0x45,
+ 0x4c, 0x10, 0x04, 0x12, 0x21, 0x0a, 0x1d, 0x46, 0x49, 0x58, 0x45, 0x44, 0x5f, 0x56, 0x41, 0x4c,
+ 0x55, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x41, 0x4e, 0x55, 0x46, 0x41, 0x43, 0x54,
+ 0x55, 0x52, 0x45, 0x52, 0x10, 0x05, 0x12, 0x1d, 0x0a, 0x19, 0x46, 0x49, 0x58, 0x45, 0x44, 0x5f,
+ 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4c, 0x4f, 0x43, 0x41, 0x54,
+ 0x49, 0x4f, 0x4e, 0x10, 0x06, 0x12, 0x1f, 0x0a, 0x1b, 0x46, 0x49, 0x58, 0x45, 0x44, 0x5f, 0x56,
+ 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x49, 0x4e, 0x45, 0x52, 0x5f,
+ 0x4e, 0x41, 0x4d, 0x45, 0x10, 0x07, 0x2a, 0x6e, 0x0a, 0x10, 0x43, 0x68, 0x61, 0x72, 0x61, 0x63,
+ 0x74, 0x65, 0x72, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x1d, 0x43, 0x48,
+ 0x41, 0x52, 0x41, 0x43, 0x54, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f,
+ 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1b, 0x0a,
+ 0x17, 0x43, 0x48, 0x41, 0x52, 0x41, 0x43, 0x54, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x43, 0x54, 0x49,
+ 0x4f, 0x4e, 0x5f, 0x46, 0x49, 0x52, 0x53, 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x48,
+ 0x41, 0x52, 0x41, 0x43, 0x54, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f,
+ 0x4c, 0x41, 0x53, 0x54, 0x10, 0x02, 0x2a, 0x87, 0x01, 0x0a, 0x0d, 0x51, 0x75, 0x61, 0x6c, 0x69,
+ 0x66, 0x69, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1e, 0x0a, 0x1a, 0x51, 0x55, 0x41, 0x4c,
+ 0x49, 0x46, 0x49, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45,
+ 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x51, 0x55, 0x41, 0x4c,
+ 0x49, 0x46, 0x49, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x55, 0x49, 0x4c, 0x44,
+ 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x51, 0x55, 0x41, 0x4c, 0x49, 0x46, 0x49,
+ 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x52, 0x41, 0x43, 0x4b, 0x10, 0x02, 0x12, 0x20,
+ 0x0a, 0x1c, 0x51, 0x55, 0x41, 0x4c, 0x49, 0x46, 0x49, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45,
+ 0x5f, 0x52, 0x41, 0x43, 0x4b, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x03,
+ 0x32, 0x9f, 0x09, 0x0a, 0x16, 0x46, 0x6c, 0x65, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65,
+ 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x82, 0x01, 0x0a, 0x17,
+ 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x6e,
+ 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x12, 0x32, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d,
+ 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73,
+ 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73,
+ 0x68, 0x6f, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x66, 0x6c,
+ 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31,
+ 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53,
+ 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+ 0x12, 0x64, 0x0a, 0x0d, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x4d, 0x69, 0x6e, 0x65, 0x72,
+ 0x73, 0x12, 0x28, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d,
+ 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x4d, 0x69,
+ 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x66, 0x6c,
+ 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31,
+ 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65,
+ 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x75, 0x0a, 0x12, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74,
+ 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x73, 0x76, 0x12, 0x2d, 0x2e, 0x66,
0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76,
0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x69, 0x73,
- 0x74, 0x43, 0x73, 0x76, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x76,
- 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43,
- 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x2e, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e,
- 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x69,
- 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65,
- 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e,
+ 0x74, 0x43, 0x73, 0x76, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x66, 0x6c,
+ 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31,
+ 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74,
+ 0x43, 0x73, 0x76, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x76, 0x0a,
+ 0x13, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x6f,
+ 0x75, 0x6e, 0x74, 0x73, 0x12, 0x2e, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61,
+ 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e,
+ 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71,
+ 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61,
+ 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e,
+ 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73,
+ 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x82, 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e,
+ 0x65, 0x72, 0x50, 0x6f, 0x6f, 0x6c, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74,
+ 0x73, 0x12, 0x32, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d,
+ 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x50,
+ 0x6f, 0x6f, 0x6c, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65,
+ 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e,
0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x69,
- 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65,
- 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x82, 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x4d, 0x69,
0x6e, 0x65, 0x72, 0x50, 0x6f, 0x6f, 0x6c, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e,
- 0x74, 0x73, 0x12, 0x32, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65,
- 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72,
- 0x50, 0x6f, 0x6f, 0x6c, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52,
- 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61,
- 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d,
- 0x69, 0x6e, 0x65, 0x72, 0x50, 0x6f, 0x6f, 0x6c, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65,
- 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, 0x13, 0x47,
- 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6f, 0x6c, 0x69, 0x6e, 0x67, 0x4d, 0x6f,
- 0x64, 0x65, 0x12, 0x2e, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65,
- 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72,
- 0x43, 0x6f, 0x6f, 0x6c, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
- 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65,
- 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72,
- 0x43, 0x6f, 0x6f, 0x6c, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f,
- 0x6e, 0x73, 0x65, 0x12, 0x61, 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x69, 0x6e,
- 0x65, 0x72, 0x73, 0x12, 0x27, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67,
- 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d,
- 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x66,
+ 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, 0x13, 0x47, 0x65,
+ 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6f, 0x6c, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64,
+ 0x65, 0x12, 0x2e, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d,
+ 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x43,
+ 0x6f, 0x6f, 0x6c, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+ 0x74, 0x1a, 0x2f, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d,
+ 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x43,
+ 0x6f, 0x6f, 0x6c, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+ 0x73, 0x65, 0x12, 0x61, 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x69, 0x6e, 0x65,
+ 0x72, 0x73, 0x12, 0x27, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65,
+ 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x69,
+ 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x66, 0x6c,
+ 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31,
+ 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73,
+ 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x65,
+ 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x2e, 0x2e, 0x66,
0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76,
- 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65,
- 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e,
- 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x2e, 0x2e,
- 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e,
- 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x6c,
- 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e,
+ 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x47,
+ 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x66,
+ 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76,
+ 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x47,
+ 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x61, 0x0a,
+ 0x0c, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x27, 0x2e,
0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e,
- 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x6c,
- 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x61,
- 0x0a, 0x0c, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x27,
- 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74,
- 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x73,
- 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d,
- 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6e,
- 0x61, 0x6d, 0x65, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
- 0x65, 0x12, 0x70, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x65,
- 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x2c, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61,
- 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61,
- 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x71,
- 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61,
- 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
- 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
- 0x6e, 0x73, 0x65, 0x42, 0xf0, 0x01, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x66, 0x6c, 0x65, 0x65,
- 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x42, 0x14,
- 0x46, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x50,
- 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x57, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
- 0x6f, 0x6d, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x66,
- 0x6c, 0x65, 0x65, 0x74, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x67, 0x65, 0x6e, 0x65,
- 0x72, 0x61, 0x74, 0x65, 0x64, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x66, 0x6c, 0x65, 0x65, 0x74,
- 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x76, 0x31, 0x3b, 0x66, 0x6c,
- 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x76, 0x31, 0xa2,
- 0x02, 0x03, 0x46, 0x58, 0x58, 0xaa, 0x02, 0x12, 0x46, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e,
- 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x12, 0x46, 0x6c, 0x65,
- 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5c, 0x56, 0x31, 0xe2,
- 0x02, 0x1e, 0x46, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e,
- 0x74, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
- 0xea, 0x02, 0x13, 0x46, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65,
- 0x6e, 0x74, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+ 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52,
+ 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61,
+ 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6e, 0x61,
+ 0x6d, 0x65, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+ 0x12, 0x70, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72,
+ 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x2c, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e,
+ 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74,
+ 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75,
+ 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67,
+ 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57,
+ 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+ 0x73, 0x65, 0x42, 0xf0, 0x01, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74,
+ 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x42, 0x14, 0x46,
+ 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x72,
+ 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x57, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
+ 0x6d, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x66, 0x6c,
+ 0x65, 0x65, 0x74, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72,
+ 0x61, 0x74, 0x65, 0x64, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6d,
+ 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x76, 0x31, 0x3b, 0x66, 0x6c, 0x65,
+ 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x76, 0x31, 0xa2, 0x02,
+ 0x03, 0x46, 0x58, 0x58, 0xaa, 0x02, 0x12, 0x46, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61,
+ 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x12, 0x46, 0x6c, 0x65, 0x65,
+ 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5c, 0x56, 0x31, 0xe2, 0x02,
+ 0x1e, 0x46, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74,
+ 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea,
+ 0x02, 0x13, 0x46, 0x6c, 0x65, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e,
+ 0x74, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
})
var (
diff --git a/server/generated/sqlc/db.go b/server/generated/sqlc/db.go
index 948ba8b95..77d1368ad 100644
--- a/server/generated/sqlc/db.go
+++ b/server/generated/sqlc/db.go
@@ -468,6 +468,9 @@ func Prepare(ctx context.Context, db DBTX) (*Queries, error) {
if q.getDeviceWithCredentialsAndIPByDeviceIdentifierStmt, err = db.PrepareContext(ctx, getDeviceWithCredentialsAndIPByDeviceIdentifier); err != nil {
return nil, fmt.Errorf("error preparing query GetDeviceWithCredentialsAndIPByDeviceIdentifier: %w", err)
}
+ if q.getDirectProtoMinerProxyTargetStmt, err = db.PrepareContext(ctx, getDirectProtoMinerProxyTarget); err != nil {
+ return nil, fmt.Errorf("error preparing query GetDirectProtoMinerProxyTarget: %w", err)
+ }
if q.getDiscoveredDeviceByDeviceIdentifierStmt, err = db.PrepareContext(ctx, getDiscoveredDeviceByDeviceIdentifier); err != nil {
return nil, fmt.Errorf("error preparing query GetDiscoveredDeviceByDeviceIdentifier: %w", err)
}
@@ -2044,6 +2047,11 @@ func (q *Queries) Close() error {
err = fmt.Errorf("error closing getDeviceWithCredentialsAndIPByDeviceIdentifierStmt: %w", cerr)
}
}
+ if q.getDirectProtoMinerProxyTargetStmt != nil {
+ if cerr := q.getDirectProtoMinerProxyTargetStmt.Close(); cerr != nil {
+ err = fmt.Errorf("error closing getDirectProtoMinerProxyTargetStmt: %w", cerr)
+ }
+ }
if q.getDiscoveredDeviceByDeviceIdentifierStmt != nil {
if cerr := q.getDiscoveredDeviceByDeviceIdentifierStmt.Close(); cerr != nil {
err = fmt.Errorf("error closing getDiscoveredDeviceByDeviceIdentifierStmt: %w", cerr)
@@ -3616,6 +3624,7 @@ type Queries struct {
getDeviceStatusForDeviceIdentifiersStmt *sql.Stmt
getDeviceStatusHourlyAggregatesStmt *sql.Stmt
getDeviceWithCredentialsAndIPByDeviceIdentifierStmt *sql.Stmt
+ getDirectProtoMinerProxyTargetStmt *sql.Stmt
getDiscoveredDeviceByDeviceIdentifierStmt *sql.Stmt
getDiscoveredDeviceByIDStmt *sql.Stmt
getDiscoveredDeviceByIPAndPortStmt *sql.Stmt
@@ -4047,6 +4056,7 @@ func (q *Queries) WithTx(tx *sql.Tx) *Queries {
getDeviceStatusForDeviceIdentifiersStmt: q.getDeviceStatusForDeviceIdentifiersStmt,
getDeviceStatusHourlyAggregatesStmt: q.getDeviceStatusHourlyAggregatesStmt,
getDeviceWithCredentialsAndIPByDeviceIdentifierStmt: q.getDeviceWithCredentialsAndIPByDeviceIdentifierStmt,
+ getDirectProtoMinerProxyTargetStmt: q.getDirectProtoMinerProxyTargetStmt,
getDiscoveredDeviceByDeviceIdentifierStmt: q.getDiscoveredDeviceByDeviceIdentifierStmt,
getDiscoveredDeviceByIDStmt: q.getDiscoveredDeviceByIDStmt,
getDiscoveredDeviceByIPAndPortStmt: q.getDiscoveredDeviceByIPAndPortStmt,
diff --git a/server/generated/sqlc/device.sql.go b/server/generated/sqlc/device.sql.go
index 5f71169b3..da6e9b582 100644
--- a/server/generated/sqlc/device.sql.go
+++ b/server/generated/sqlc/device.sql.go
@@ -1789,7 +1789,8 @@ SELECT
d.site_id,
COALESCE(s.name, '') as site_label,
d.building_id,
- COALESCE(b.name, '') as building_label
+ COALESCE(b.name, '') as building_label,
+ FALSE as embedded_web_view_available
FROM discovered_device dd
LEFT JOIN device d ON dd.id = d.discovered_device_id
LEFT JOIN device_pairing dp ON d.id = dp.device_id
@@ -1800,28 +1801,29 @@ WHERE FALSE
`
type ListMinerStateSnapshotsRow struct {
- DeviceIdentifier string
- MacAddress string
- SerialNumber sql.NullString
- Model sql.NullString
- Manufacturer sql.NullString
- FirmwareVersion sql.NullString
- WorkerName sql.NullString
- DeviceStatus NullDeviceStatusEnum
- StatusTimestamp sql.NullTime
- StatusDetails sql.NullString
- IpAddress string
- Port string
- UrlScheme string
- PairingStatus string
- CursorID int64
- DeviceID int64
- DriverName string
- CustomName sql.NullString
- SiteID sql.NullInt64
- SiteLabel string
- BuildingID sql.NullInt64
- BuildingLabel string
+ DeviceIdentifier string
+ MacAddress string
+ SerialNumber sql.NullString
+ Model sql.NullString
+ Manufacturer sql.NullString
+ FirmwareVersion sql.NullString
+ WorkerName sql.NullString
+ DeviceStatus NullDeviceStatusEnum
+ StatusTimestamp sql.NullTime
+ StatusDetails sql.NullString
+ IpAddress string
+ Port string
+ UrlScheme string
+ PairingStatus string
+ CursorID int64
+ DeviceID int64
+ DriverName string
+ CustomName sql.NullString
+ SiteID sql.NullInt64
+ SiteLabel string
+ BuildingID sql.NullInt64
+ BuildingLabel string
+ EmbeddedWebViewAvailable bool
}
// TYPE GENERATION STUB - This query is never executed.
@@ -1860,6 +1862,7 @@ func (q *Queries) ListMinerStateSnapshots(ctx context.Context) ([]ListMinerState
&i.SiteLabel,
&i.BuildingID,
&i.BuildingLabel,
+ &i.EmbeddedWebViewAvailable,
); err != nil {
return nil, err
}
diff --git a/server/generated/sqlc/miner_service.sql.go b/server/generated/sqlc/miner_service.sql.go
index 8ab595669..3a116ccf0 100644
--- a/server/generated/sqlc/miner_service.sql.go
+++ b/server/generated/sqlc/miner_service.sql.go
@@ -142,3 +142,75 @@ func (q *Queries) GetDeviceWithCredentialsAndIPByDeviceIdentifier(ctx context.Co
)
return i, err
}
+
+const getDirectProtoMinerProxyTarget = `-- name: GetDirectProtoMinerProxyTarget :one
+SELECT
+ d.id,
+ d.device_identifier,
+ d.org_id,
+ d.site_id,
+ d.serial_number,
+ d.mac_address,
+ dd.ip_address,
+ dd.port,
+ dd.url_scheme,
+ dd.driver_name,
+ mc.username_enc,
+ mc.password_enc
+FROM device d
+JOIN discovered_device dd ON d.discovered_device_id = dd.id
+JOIN device_pairing dp ON d.id = dp.device_id
+LEFT JOIN miner_credentials mc ON d.id = mc.device_id
+WHERE d.device_identifier = $1
+ AND d.org_id = $2
+ AND d.deleted_at IS NULL
+ AND dp.pairing_status IN ('PAIRED', 'DEFAULT_PASSWORD')
+ AND dd.driver_name = 'proto'
+ -- This HTTP proxy dials the miner from fleet-api. Fleet-node-owned
+ -- devices need a result-capable typed control command instead.
+ AND NOT EXISTS (
+ SELECT 1 FROM fleet_node_device fnd
+ WHERE fnd.device_id = d.id AND fnd.org_id = d.org_id
+ )
+LIMIT 1
+`
+
+type GetDirectProtoMinerProxyTargetParams struct {
+ DeviceIdentifier string
+ OrgID int64
+}
+
+type GetDirectProtoMinerProxyTargetRow struct {
+ ID int64
+ DeviceIdentifier string
+ OrgID int64
+ SiteID sql.NullInt64
+ SerialNumber sql.NullString
+ MacAddress string
+ IpAddress string
+ Port string
+ UrlScheme string
+ DriverName string
+ UsernameEnc sql.NullString
+ PasswordEnc sql.NullString
+}
+
+func (q *Queries) GetDirectProtoMinerProxyTarget(ctx context.Context, arg GetDirectProtoMinerProxyTargetParams) (GetDirectProtoMinerProxyTargetRow, error) {
+ row := q.queryRow(ctx, q.getDirectProtoMinerProxyTargetStmt, getDirectProtoMinerProxyTarget, arg.DeviceIdentifier, arg.OrgID)
+ var i GetDirectProtoMinerProxyTargetRow
+ err := row.Scan(
+ &i.ID,
+ &i.DeviceIdentifier,
+ &i.OrgID,
+ &i.SiteID,
+ &i.SerialNumber,
+ &i.MacAddress,
+ &i.IpAddress,
+ &i.Port,
+ &i.UrlScheme,
+ &i.DriverName,
+ &i.UsernameEnc,
+ &i.PasswordEnc,
+ )
+ return i, err
+}
diff --git a/server/internal/domain/fleetmanagement/service.go b/server/internal/domain/fleetmanagement/service.go
index ceb9c2e0d..287b915fe 100644
--- a/server/internal/domain/fleetmanagement/service.go
+++ b/server/internal/domain/fleetmanagement/service.go
@@ -701,8 +701,9 @@ func (s *Service) buildSnapshotsFromUnifiedQuery(
snapshots := make([]*pb.MinerStateSnapshot, 0, len(rows))
for _, row := range rows {
snapshot := &pb.MinerStateSnapshot{
- DeviceIdentifier: row.DeviceIdentifier,
- DriverName: row.DriverName,
+ DeviceIdentifier: row.DeviceIdentifier,
+ DriverName: row.DriverName,
+ EmbeddedWebViewAvailable: row.EmbeddedWebViewAvailable,
}
if row.SiteID.Valid {
diff --git a/server/internal/domain/stores/sqlstores/device.go b/server/internal/domain/stores/sqlstores/device.go
index 11710a98c..5a7ea4907 100644
--- a/server/internal/domain/stores/sqlstores/device.go
+++ b/server/internal/domain/stores/sqlstores/device.go
@@ -1094,6 +1094,7 @@ func (s *SQLDeviceStore) executeListQuery(ctx context.Context, orgID int64, curs
&row.SiteLabel,
&row.BuildingID,
&row.BuildingLabel,
+ &row.EmbeddedWebViewAvailable,
&row.SortValue,
)
if err != nil {
diff --git a/server/internal/domain/stores/sqlstores/device_integration_test.go b/server/internal/domain/stores/sqlstores/device_integration_test.go
index b909710f0..dba1c4912 100644
--- a/server/internal/domain/stores/sqlstores/device_integration_test.go
+++ b/server/internal/domain/stores/sqlstores/device_integration_test.go
@@ -734,6 +734,94 @@ func TestCountMinersByState_FilterConsistency(t *testing.T) {
require.False(t, identifiers["device-002"], "should NOT include INACTIVE device with error")
}
+func TestListMinerStateSnapshots_EmbeddedWebViewAvailable(t *testing.T) {
+ if testing.Short() {
+ t.Skip("Skipping database integration test in short mode")
+ }
+
+ conn := testutil.GetTestDB(t)
+ ctx := t.Context()
+ store := sqlstores.NewSQLDeviceStore(conn)
+
+ _, err := conn.Exec(`
+ INSERT INTO organization (id, org_id, name)
+ VALUES (1, '00000000-0000-0000-0000-000000000001', 'Test Org')
+ `)
+ require.NoError(t, err)
+
+ fixtures := []struct {
+ id int64
+ identifier string
+ driverName string
+ pairingStatus string
+ fleetNodeOwned bool
+ wantAvailable bool
+ }{
+ {id: 9101, identifier: "direct-paired-proto", driverName: "proto", pairingStatus: "PAIRED", wantAvailable: true},
+ {id: 9102, identifier: "direct-default-proto", driverName: "proto", pairingStatus: "DEFAULT_PASSWORD", wantAvailable: true},
+ {id: 9103, identifier: "direct-auth-proto", driverName: "proto", pairingStatus: "AUTHENTICATION_NEEDED"},
+ {id: 9104, identifier: "direct-paired-ant", driverName: "antminer", pairingStatus: "PAIRED"},
+ {id: 9105, identifier: "discovered-only-proto", driverName: "proto"},
+ {id: 9106, identifier: "fleet-node-proto", driverName: "proto", pairingStatus: "PAIRED", fleetNodeOwned: true},
+ }
+
+ var fleetNodeID int64
+ require.NoError(t, conn.QueryRow(`
+ INSERT INTO fleet_node (org_id, name, identity_pubkey, enrollment_status)
+ VALUES (1, $1, $2, 'CONFIRMED')
+ RETURNING id
+ `, "web-view-node", []byte("web-view-node-key")).Scan(&fleetNodeID))
+
+ identifiers := make([]string, 0, len(fixtures))
+ for i, fixture := range fixtures {
+ identifiers = append(identifiers, fixture.identifier)
+ _, err := conn.Exec(`
+ INSERT INTO discovered_device (id, org_id, device_identifier, model, manufacturer, driver_name, ip_address, port, url_scheme, is_active)
+ VALUES ($1, 1, $2, 'test-model', 'test-manufacturer', $3, $4, '50051', 'http', TRUE)
+ `, fixture.id, fixture.identifier, fixture.driverName, fmt.Sprintf("10.42.0.%d", i+1))
+ require.NoError(t, err)
+
+ if fixture.pairingStatus == "" {
+ continue
+ }
+
+ _, err = conn.Exec(`
+ INSERT INTO device (id, org_id, discovered_device_id, device_identifier, mac_address)
+ VALUES ($1, 1, $1, $2, $3)
+ `, fixture.id, fixture.identifier, fmt.Sprintf("AA:BB:CC:DD:EE:%02d", i+1))
+ require.NoError(t, err)
+
+ _, err = conn.Exec(`
+ INSERT INTO device_pairing (device_id, pairing_status, paired_at)
+ VALUES ($1, $2, NOW())
+ `, fixture.id, fixture.pairingStatus)
+ require.NoError(t, err)
+
+ if fixture.fleetNodeOwned {
+ _, err = conn.Exec(`
+ INSERT INTO fleet_node_device (fleet_node_id, device_id, org_id)
+ VALUES ($1, $2, 1)
+ `, fleetNodeID, fixture.id)
+ require.NoError(t, err)
+ }
+ }
+
+ rows, _, total, err := store.ListMinerStateSnapshots(ctx, 1, "", 100, &interfaces.MinerFilter{
+ DeviceIdentifiers: identifiers,
+ }, nil)
+ require.NoError(t, err)
+ require.Equal(t, int64(len(fixtures)), total)
+
+ byIdentifier := make(map[string]bool, len(rows))
+ for _, row := range rows {
+ byIdentifier[row.DeviceIdentifier] = row.EmbeddedWebViewAvailable
+ }
+
+ for _, fixture := range fixtures {
+ require.Equal(t, fixture.wantAvailable, byIdentifier[fixture.identifier], fixture.identifier)
+ }
+}
+
// TestCountMinersByState_AuthNeededNullStatus verifies auth-needed miners with
// NULL device_status go to broken_count, not offline_count.
func TestCountMinersByState_AuthNeededNullStatus(t *testing.T) {
diff --git a/server/internal/domain/stores/sqlstores/device_query_fragments.go b/server/internal/domain/stores/sqlstores/device_query_fragments.go
index eb1c52ba8..0037f1ded 100644
--- a/server/internal/domain/stores/sqlstores/device_query_fragments.go
+++ b/server/internal/domain/stores/sqlstores/device_query_fragments.go
@@ -20,6 +20,16 @@ import (
// or the actual pairing status for paired devices.
const pairingStatusExpr = "CASE WHEN device.id IS NOT NULL THEN COALESCE(device_pairing.pairing_status::text, 'UNPAIRED') ELSE 'UNPAIRED' END"
+const embeddedWebViewAvailableExpr = `(
+ device.id IS NOT NULL
+ AND COALESCE(device_pairing.pairing_status::text, 'UNPAIRED') IN ('PAIRED', 'DEFAULT_PASSWORD')
+ AND discovered_device.driver_name = 'proto'
+ AND NOT EXISTS (
+ SELECT 1 FROM fleet_node_device fnd
+ WHERE fnd.device_id = device.id AND fnd.org_id = device.org_id
+ )
+)`
+
// minerSelectColumns contains the common SELECT columns for miner state queries.
const minerSelectColumns = `SELECT
discovered_device.device_identifier,
@@ -43,7 +53,8 @@ const minerSelectColumns = `SELECT
device.site_id,
COALESCE(site.name, '') as site_label,
device.building_id,
- COALESCE(building.name, '') as building_label`
+ COALESCE(building.name, '') as building_label,
+ ` + embeddedWebViewAvailableExpr + ` as embedded_web_view_available`
// minerFromJoins contains the FROM clause and LEFT JOINs for miner state queries.
// Parameter: $1 = org_id (used in device join condition)
diff --git a/server/internal/handlers/minerproxy/handler.go b/server/internal/handlers/minerproxy/handler.go
new file mode 100644
index 000000000..5ead903cd
--- /dev/null
+++ b/server/internal/handlers/minerproxy/handler.go
@@ -0,0 +1,518 @@
+package minerproxy
+
+import (
+ "bytes"
+ "context"
+ "crypto/tls"
+ "database/sql"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "log/slog"
+ "net"
+ "net/http"
+ "net/url"
+ "strings"
+ "sync"
+ "time"
+
+ "connectrpc.com/authn"
+
+ "github.com/block/proto-fleet/server/generated/sqlc"
+ "github.com/block/proto-fleet/server/internal/domain/authz"
+ "github.com/block/proto-fleet/server/internal/domain/fleeterror"
+ "github.com/block/proto-fleet/server/internal/domain/session"
+ stores "github.com/block/proto-fleet/server/internal/domain/stores/interfaces"
+ "github.com/block/proto-fleet/server/internal/handlers/middleware"
+ "github.com/block/proto-fleet/server/internal/infrastructure/db"
+ "github.com/block/proto-fleet/server/internal/infrastructure/encrypt"
+)
+
+const (
+ proxyClientTimeout = 30 * time.Second
+ maxProxyBodyBytes = 64 << 20
+ defaultProtoURLScheme = "http"
+)
+
+type errorResponse struct {
+ Error string `json:"error"`
+}
+
+type loginRequest struct {
+ Password string `json:"password"`
+}
+
+type loginResponse struct {
+ AccessToken string `json:"access_token"`
+}
+
+type Handler struct {
+ queries *sqlc.Queries
+ sessionService *session.Service
+ userStore stores.UserStore
+ permissionResolver *authz.PermissionResolver
+ encryptService *encrypt.Service
+ httpClient *http.Client
+ httpsClient *http.Client
+
+ tokenMu sync.Mutex
+ tokens map[string]string
+}
+
+type proxyTarget struct {
+ deviceIdentifier string
+ baseURL string
+ siteID *int64
+ passwordEnc sql.NullString
+}
+
+func NewHandler(
+ conn *sql.DB,
+ sessionService *session.Service,
+ userStore stores.UserStore,
+ permissionResolver *authz.PermissionResolver,
+ encryptService *encrypt.Service,
+) http.Handler {
+ return &Handler{
+ queries: sqlc.New(db.NewRetryDB(conn)),
+ sessionService: sessionService,
+ userStore: userStore,
+ permissionResolver: permissionResolver,
+ encryptService: encryptService,
+ httpClient: newProxyHTTPClient(false),
+ httpsClient: newProxyHTTPClient(true),
+ tokens: make(map[string]string),
+ }
+}
+
+func newProxyHTTPClient(skipVerify bool) *http.Client {
+ transport := &http.Transport{
+ MaxIdleConns: 100,
+ MaxIdleConnsPerHost: 10,
+ IdleConnTimeout: 90 * time.Second,
+ TLSHandshakeTimeout: 10 * time.Second,
+ ResponseHeaderTimeout: proxyClientTimeout,
+ ForceAttemptHTTP2: skipVerify,
+ }
+ if skipVerify {
+ transport.TLSClientConfig = &tls.Config{
+ // Proto rigs commonly present self-signed certs. This matches the
+ // Proto plugin's transport behavior.
+ InsecureSkipVerify: true, // #nosec G402 -- intentional for Proto rig HTTPS
+ MinVersion: tls.VersionTLS12,
+ }
+ }
+ return &http.Client{
+ Transport: transport,
+ Timeout: proxyClientTimeout,
+ CheckRedirect: func(*http.Request, []*http.Request) error {
+ return http.ErrUseLastResponse
+ },
+ }
+}
+
+func (h *Handler) clientFor(baseURL string) *http.Client {
+ if strings.HasPrefix(baseURL, "https://") {
+ return h.httpsClient
+ }
+ return h.httpClient
+}
+
+func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ ctx, info, err := h.authenticate(r)
+ if err != nil {
+ slog.Warn("miner proxy authentication failed", "error", err)
+ writeError(w, httpStatusForError(err), "authentication required")
+ return
+ }
+
+ deviceIdentifier := r.PathValue("deviceIdentifier")
+ rest := r.PathValue("rest")
+ if deviceIdentifier == "" || rest == "" {
+ writeError(w, http.StatusNotFound, "miner API route not found")
+ return
+ }
+
+ target, err := h.resolveTarget(ctx, deviceIdentifier, info.OrganizationID)
+ if err != nil {
+ writeError(w, httpStatusForError(err), clientMessageForError(err))
+ return
+ }
+
+ proxyPath := "/api/v1/" + rest
+ requiredPermission := permissionFor(r.Method, proxyPath)
+ if _, err := middleware.RequirePermission(ctx, requiredPermission, authz.ResourceContext{SiteID: target.siteID}); err != nil {
+ writeError(w, httpStatusForError(err), clientMessageForError(err))
+ return
+ }
+
+ body, err := readProxyBody(w, r)
+ if err != nil {
+ writeError(w, http.StatusRequestEntityTooLarge, err.Error())
+ return
+ }
+
+ resp, err := h.forward(ctx, r, target, proxyPath, body, false)
+ if err != nil {
+ writeError(w, httpStatusForError(err), clientMessageForError(err))
+ return
+ }
+ defer resp.Body.Close()
+
+ if resp.StatusCode == http.StatusUnauthorized && target.passwordEnc.Valid {
+ _, _ = io.Copy(io.Discard, resp.Body)
+ h.clearToken(target.deviceIdentifier)
+ resp.Body.Close()
+
+ resp, err = h.forward(ctx, r, target, proxyPath, body, true)
+ if err != nil {
+ writeError(w, httpStatusForError(err), clientMessageForError(err))
+ return
+ }
+ defer resp.Body.Close()
+ }
+
+ copyResponseHeaders(w.Header(), resp.Header)
+ w.WriteHeader(resp.StatusCode)
+ if r.Method == http.MethodHead {
+ return
+ }
+ if _, err := io.Copy(w, resp.Body); err != nil {
+ slog.Warn("miner proxy response copy failed", "device_identifier", deviceIdentifier, "error", err)
+ }
+}
+
+func (h *Handler) authenticate(r *http.Request) (context.Context, *session.Info, error) {
+ cookie, err := r.Cookie(h.sessionService.CookieName())
+ if err != nil || cookie.Value == "" {
+ return r.Context(), nil, fleeterror.NewUnauthenticatedError("session cookie required")
+ }
+
+ sess, err := h.sessionService.Validate(r.Context(), cookie.Value)
+ if err != nil {
+ return r.Context(), nil, err
+ }
+
+ user, err := h.userStore.GetUserByID(r.Context(), sess.UserID)
+ if err != nil {
+ return r.Context(), nil, fleeterror.NewUnauthenticatedErrorf("user with id %d not found", sess.UserID)
+ }
+
+ info := &session.Info{
+ AuthMethod: session.AuthMethodSession,
+ SessionID: sess.SessionID,
+ UserID: sess.UserID,
+ OrganizationID: sess.OrganizationID,
+ ExternalUserID: user.UserID,
+ Username: user.Username,
+ }
+
+ effectivePermissions, err := h.permissionResolver.LoadEffective(r.Context(), info.UserID, info.OrganizationID)
+ if err != nil {
+ return r.Context(), nil, fleeterror.NewInternalErrorf("authz: effective permissions lookup failed: %v", err)
+ }
+
+ ctx := middleware.WithEffectivePermissions(authn.SetInfo(r.Context(), info), effectivePermissions)
+ return ctx, info, nil
+}
+
+func (h *Handler) resolveTarget(ctx context.Context, deviceIdentifier string, orgID int64) (proxyTarget, error) {
+ row, err := h.queries.GetDirectProtoMinerProxyTarget(ctx, sqlc.GetDirectProtoMinerProxyTargetParams{
+ DeviceIdentifier: deviceIdentifier,
+ OrgID: orgID,
+ })
+ if err != nil {
+ if errors.Is(err, sql.ErrNoRows) {
+ return proxyTarget{}, fleeterror.NewNotFoundError("miner not found or cannot be proxied")
+ }
+ return proxyTarget{}, fleeterror.NewInternalErrorf("failed to resolve miner proxy target: %v", err)
+ }
+
+ scheme := strings.ToLower(row.UrlScheme)
+ if scheme == "" {
+ scheme = defaultProtoURLScheme
+ }
+ if scheme != "http" && scheme != "https" {
+ return proxyTarget{}, fleeterror.NewFailedPreconditionErrorf("miner URL scheme %q cannot be proxied", row.UrlScheme)
+ }
+
+ host := row.IpAddress
+ if row.Port != "" && row.Port != "0" {
+ host = net.JoinHostPort(row.IpAddress, row.Port)
+ }
+
+ base := url.URL{Scheme: scheme, Host: host}
+ var siteID *int64
+ if row.SiteID.Valid {
+ site := row.SiteID.Int64
+ siteID = &site
+ }
+
+ return proxyTarget{
+ deviceIdentifier: row.DeviceIdentifier,
+ baseURL: base.String(),
+ siteID: siteID,
+ passwordEnc: row.PasswordEnc,
+ }, nil
+}
+
+func (h *Handler) forward(
+ ctx context.Context,
+ source *http.Request,
+ target proxyTarget,
+ proxyPath string,
+ body []byte,
+ forceLogin bool,
+) (*http.Response, error) {
+ token, err := h.tokenFor(ctx, target, forceLogin)
+ if err != nil {
+ return nil, err
+ }
+
+ targetURL := target.baseURL + proxyPath
+ if source.URL.RawQuery != "" {
+ targetURL += "?" + source.URL.RawQuery
+ }
+
+ var bodyReader io.Reader
+ if body != nil {
+ bodyReader = bytes.NewReader(body)
+ }
+ req, err := http.NewRequestWithContext(ctx, source.Method, targetURL, bodyReader)
+ if err != nil {
+ return nil, fleeterror.NewInvalidArgumentErrorf("failed to create miner proxy request: %v", err)
+ }
+ copyRequestHeaders(req.Header, source.Header)
+ if token != "" {
+ req.Header.Set("Authorization", "Bearer "+token)
+ } else {
+ req.Header.Del("Authorization")
+ }
+
+ resp, err := h.clientFor(target.baseURL).Do(req)
+ if err != nil {
+ return nil, fleeterror.NewUnavailableErrorf("failed to reach miner: %v", err)
+ }
+ return resp, nil
+}
+
+func (h *Handler) tokenFor(ctx context.Context, target proxyTarget, forceLogin bool) (string, error) {
+ if !target.passwordEnc.Valid || target.passwordEnc.String == "" {
+ return "", nil
+ }
+
+ if !forceLogin {
+ h.tokenMu.Lock()
+ token := h.tokens[target.deviceIdentifier]
+ h.tokenMu.Unlock()
+ if token != "" {
+ return token, nil
+ }
+ }
+
+ passwordBytes, err := h.encryptService.Decrypt(target.passwordEnc.String)
+ if err != nil {
+ return "", fleeterror.NewInternalErrorf("failed to decrypt miner credentials: %v", err)
+ }
+
+ token, err := h.login(ctx, target.baseURL, string(passwordBytes))
+ if err != nil {
+ return "", err
+ }
+
+ h.tokenMu.Lock()
+ h.tokens[target.deviceIdentifier] = token
+ h.tokenMu.Unlock()
+ return token, nil
+}
+
+func (h *Handler) clearToken(deviceIdentifier string) {
+ h.tokenMu.Lock()
+ defer h.tokenMu.Unlock()
+ delete(h.tokens, deviceIdentifier)
+}
+
+func (h *Handler) login(ctx context.Context, baseURL string, password string) (string, error) {
+ body, err := json.Marshal(loginRequest{Password: password})
+ if err != nil {
+ return "", fleeterror.NewInternalErrorf("failed to create miner login request: %v", err)
+ }
+
+ req, err := http.NewRequestWithContext(ctx, http.MethodPost, baseURL+"/api/v1/auth/login", bytes.NewReader(body))
+ if err != nil {
+ return "", fleeterror.NewInternalErrorf("failed to create miner login request: %v", err)
+ }
+ req.Header.Set("Content-Type", "application/json")
+
+ resp, err := h.clientFor(baseURL).Do(req)
+ if err != nil {
+ return "", fleeterror.NewUnavailableErrorf("failed to authenticate with miner: %v", err)
+ }
+ defer resp.Body.Close()
+
+ if resp.StatusCode == http.StatusUnauthorized {
+ _, _ = io.Copy(io.Discard, resp.Body)
+ return "", fleeterror.NewUnauthenticatedError("stored miner credentials were rejected")
+ }
+ if resp.StatusCode != http.StatusOK {
+ _, _ = io.Copy(io.Discard, resp.Body)
+ return "", fleeterror.NewFailedPreconditionErrorf("miner login failed with status %d", resp.StatusCode)
+ }
+
+ var tokens loginResponse
+ if err := json.NewDecoder(resp.Body).Decode(&tokens); err != nil {
+ return "", fleeterror.NewInternalErrorf("failed to decode miner login response: %v", err)
+ }
+ if tokens.AccessToken == "" {
+ return "", fleeterror.NewInternalError("miner login response did not include an access token")
+ }
+ return tokens.AccessToken, nil
+}
+
+func readProxyBody(w http.ResponseWriter, r *http.Request) ([]byte, error) {
+ if r.Body == nil || r.Body == http.NoBody {
+ return nil, nil
+ }
+ defer r.Body.Close()
+
+ reader := http.MaxBytesReader(w, r.Body, maxProxyBodyBytes)
+ body, err := io.ReadAll(reader)
+ if err != nil {
+ return nil, fmt.Errorf("proxied request body exceeds %d bytes", maxProxyBodyBytes)
+ }
+ if len(body) == 0 {
+ return nil, nil
+ }
+ return body, nil
+}
+
+func permissionFor(method string, proxyPath string) string {
+ if strings.HasPrefix(proxyPath, "/api/v1/system/logs") {
+ return authz.PermMinerDownloadLogs
+ }
+
+ if method == http.MethodGet || method == http.MethodHead {
+ return authz.PermMinerRead
+ }
+
+ switch {
+ case proxyPath == "/api/v1/timeseries":
+ return authz.PermMinerRead
+ case strings.HasPrefix(proxyPath, "/api/v1/pools"):
+ return authz.PermMinerUpdatePools
+ case proxyPath == "/api/v1/cooling":
+ return authz.PermMinerSetCoolingMode
+ case proxyPath == "/api/v1/mining/target" || proxyPath == "/api/v1/mining/tuning":
+ return authz.PermMinerSetPowerTarget
+ case proxyPath == "/api/v1/mining/start":
+ return authz.PermMinerStartMining
+ case proxyPath == "/api/v1/mining/stop":
+ return authz.PermMinerStopMining
+ case proxyPath == "/api/v1/system/reboot":
+ return authz.PermMinerReboot
+ case proxyPath == "/api/v1/system/locate":
+ return authz.PermMinerBlinkLED
+ case strings.HasPrefix(proxyPath, "/api/v1/system/update"):
+ return authz.PermMinerFirmwareUpdate
+ case proxyPath == "/api/v1/power-supplies/update":
+ return authz.PermMinerFirmwareUpdate
+ case strings.HasPrefix(proxyPath, "/api/v1/system/tag"):
+ return authz.PermMinerRename
+ case strings.HasPrefix(proxyPath, "/api/v1/auth/"):
+ return authz.PermMinerUpdatePassword
+ case proxyPath == "/api/v1/system/ssh" ||
+ proxyPath == "/api/v1/system/unlock" ||
+ proxyPath == "/api/v1/network" ||
+ proxyPath == "/api/v1/system/telemetry" ||
+ strings.HasPrefix(proxyPath, "/api/v1/pairing/auth-key"):
+ return authz.PermMinerUpdatePassword
+ default:
+ // Device settings still need finer-grained Fleet permissions. Until
+ // then, require an elevated miner setting permission for any mutating
+ // ProtoOS endpoint that is not explicitly classified above.
+ return authz.PermMinerUpdatePassword
+ }
+}
+
+func copyRequestHeaders(dst http.Header, src http.Header) {
+ for key, values := range src {
+ if shouldSkipRequestHeader(key) {
+ continue
+ }
+ for _, value := range values {
+ dst.Add(key, value)
+ }
+ }
+}
+
+func copyResponseHeaders(dst http.Header, src http.Header) {
+ for key, values := range src {
+ if shouldSkipResponseHeader(key) {
+ continue
+ }
+ for _, value := range values {
+ dst.Add(key, value)
+ }
+ }
+}
+
+func shouldSkipRequestHeader(key string) bool {
+ switch strings.ToLower(key) {
+ case "authorization", "cookie", "connection", "keep-alive", "proxy-authenticate", "proxy-authorization",
+ "te", "trailer", "transfer-encoding", "upgrade", "host":
+ return true
+ default:
+ return false
+ }
+}
+
+func shouldSkipResponseHeader(key string) bool {
+ switch strings.ToLower(key) {
+ case "connection", "keep-alive", "proxy-authenticate", "proxy-authorization", "te", "trailer",
+ "transfer-encoding", "upgrade", "set-cookie":
+ return true
+ default:
+ return false
+ }
+}
+
+func httpStatusForError(err error) int {
+ switch {
+ case fleeterror.IsAuthenticationError(err):
+ return http.StatusUnauthorized
+ case fleeterror.IsForbiddenError(err):
+ return http.StatusForbidden
+ case fleeterror.IsNotFoundError(err):
+ return http.StatusNotFound
+ case fleeterror.IsInvalidArgumentError(err):
+ return http.StatusBadRequest
+ case fleeterror.IsFailedPreconditionError(err):
+ return http.StatusPreconditionFailed
+ case fleeterror.IsUnavailableError(err):
+ return http.StatusBadGateway
+ default:
+ return http.StatusInternalServerError
+ }
+}
+
+func clientMessageForError(err error) string {
+ switch {
+ case fleeterror.IsAuthenticationError(err):
+ return "authentication required"
+ case fleeterror.IsForbiddenError(err):
+ return "permission denied"
+ case fleeterror.IsNotFoundError(err):
+ return "miner not found or cannot be proxied"
+ default:
+ return err.Error()
+ }
+}
+
+func writeError(w http.ResponseWriter, statusCode int, message string) {
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(statusCode)
+ if err := json.NewEncoder(w).Encode(errorResponse{Error: message}); err != nil {
+ slog.Error("failed to encode miner proxy error response", "error", err)
+ }
+}
diff --git a/server/internal/handlers/minerproxy/handler_test.go b/server/internal/handlers/minerproxy/handler_test.go
new file mode 100644
index 000000000..0702b2d63
--- /dev/null
+++ b/server/internal/handlers/minerproxy/handler_test.go
@@ -0,0 +1,108 @@
+package minerproxy
+
+import (
+ "net/http"
+ "testing"
+
+ "github.com/block/proto-fleet/server/internal/domain/authz"
+)
+
+func TestPermissionFor(t *testing.T) {
+ tests := []struct {
+ name string
+ method string
+ proxyPath string
+ want string
+ }{
+ {
+ name: "read endpoints require miner read",
+ method: http.MethodGet,
+ proxyPath: "/api/v1/network",
+ want: authz.PermMinerRead,
+ },
+ {
+ name: "log downloads require log download permission for get",
+ method: http.MethodGet,
+ proxyPath: "/api/v1/system/logs",
+ want: authz.PermMinerDownloadLogs,
+ },
+ {
+ name: "log downloads require log download permission for head",
+ method: http.MethodHead,
+ proxyPath: "/api/v1/system/logs",
+ want: authz.PermMinerDownloadLogs,
+ },
+ {
+ name: "timeseries post is a read-style query",
+ method: http.MethodPost,
+ proxyPath: "/api/v1/timeseries",
+ want: authz.PermMinerRead,
+ },
+ {
+ name: "pools writes require pool update",
+ method: http.MethodPut,
+ proxyPath: "/api/v1/pools/1",
+ want: authz.PermMinerUpdatePools,
+ },
+ {
+ name: "power target writes require power target permission",
+ method: http.MethodPut,
+ proxyPath: "/api/v1/mining/target",
+ want: authz.PermMinerSetPowerTarget,
+ },
+ {
+ name: "firmware writes require firmware update",
+ method: http.MethodPost,
+ proxyPath: "/api/v1/system/update",
+ want: authz.PermMinerFirmwareUpdate,
+ },
+ {
+ name: "psu firmware writes require firmware update",
+ method: http.MethodPost,
+ proxyPath: "/api/v1/power-supplies/update",
+ want: authz.PermMinerFirmwareUpdate,
+ },
+ {
+ name: "tag writes require rename",
+ method: http.MethodPut,
+ proxyPath: "/api/v1/system/tag",
+ want: authz.PermMinerRename,
+ },
+ {
+ name: "security settings writes require password update",
+ method: http.MethodPut,
+ proxyPath: "/api/v1/system/ssh",
+ want: authz.PermMinerUpdatePassword,
+ },
+ {
+ name: "unknown mutating endpoints do not fall through to read",
+ method: http.MethodPost,
+ proxyPath: "/api/v1/new-setting",
+ want: authz.PermMinerUpdatePassword,
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if got := permissionFor(tt.method, tt.proxyPath); got != tt.want {
+ t.Fatalf("permissionFor(%q, %q) = %q, want %q", tt.method, tt.proxyPath, got, tt.want)
+ }
+ })
+ }
+}
+
+func TestCopyResponseHeadersDropsSetCookie(t *testing.T) {
+ src := http.Header{}
+ src.Add("Content-Type", "application/json")
+ src.Add("Set-Cookie", "miner_session=unsafe; Path=/")
+
+ dst := http.Header{}
+ copyResponseHeaders(dst, src)
+
+ if got := dst.Get("Content-Type"); got != "application/json" {
+ t.Fatalf("Content-Type = %q, want application/json", got)
+ }
+ if got := dst.Values("Set-Cookie"); len(got) != 0 {
+ t.Fatalf("Set-Cookie values = %v, want none", got)
+ }
+}
diff --git a/server/sqlc/queries/device.sql b/server/sqlc/queries/device.sql
index 6cb1603cc..0093da31b 100644
--- a/server/sqlc/queries/device.sql
+++ b/server/sqlc/queries/device.sql
@@ -586,7 +586,8 @@ SELECT
d.site_id,
COALESCE(s.name, '') as site_label,
d.building_id,
- COALESCE(b.name, '') as building_label
+ COALESCE(b.name, '') as building_label,
+ FALSE as embedded_web_view_available
FROM discovered_device dd
LEFT JOIN device d ON dd.id = d.discovered_device_id
LEFT JOIN device_pairing dp ON d.id = dp.device_id
diff --git a/server/sqlc/queries/miner_service.sql b/server/sqlc/queries/miner_service.sql
index a682229b1..6a683e3dc 100644
--- a/server/sqlc/queries/miner_service.sql
+++ b/server/sqlc/queries/miner_service.sql
@@ -29,6 +29,37 @@ WHERE d.device_identifier = $1
)
LIMIT 1;
+-- name: GetDirectProtoMinerProxyTarget :one
+SELECT
+ d.id,
+ d.device_identifier,
+ d.org_id,
+ d.site_id,
+ d.serial_number,
+ d.mac_address,
+ dd.ip_address,
+ dd.port,
+ dd.url_scheme,
+ dd.driver_name,
+ mc.username_enc,
+ mc.password_enc
+FROM device d
+JOIN discovered_device dd ON d.discovered_device_id = dd.id
+JOIN device_pairing dp ON d.id = dp.device_id
+LEFT JOIN miner_credentials mc ON d.id = mc.device_id
+WHERE d.device_identifier = $1
+ AND d.org_id = $2
+ AND d.deleted_at IS NULL
+ AND dp.pairing_status IN ('PAIRED', 'DEFAULT_PASSWORD')
+ AND dd.driver_name = 'proto'
+ -- This HTTP proxy dials the miner from fleet-api. Fleet-node-owned
+ -- devices need a result-capable typed control command instead.
+ AND NOT EXISTS (
+ SELECT 1 FROM fleet_node_device fnd
+ WHERE fnd.device_id = d.id AND fnd.org_id = d.org_id
+ )
+LIMIT 1;
+
-- name: GetActiveFleetNodeForDevice :one
-- Resolve the active fleet node a device is paired to, with the connection
-- coordinates the node needs to reach the LAN miner. The miner service calls this