From c11fe3e1aba5aa308f47d16533232e020b6d7d88 Mon Sep 17 00:00:00 2001 From: Xavier Michelon Date: Mon, 16 May 2022 10:59:45 +0200 Subject: [PATCH] GODT-1554 / 1555: Implement gRPC go service and Qt 5 frontend C++ app. WIP: updates WIP: cache on disk and autostart. WIP: mail, keychain and more. WIP: updated grpc version in go mod file. WIP: user list. WIP: RPC service placeholder WIP: test C++ RPC client skeleton. Other: missing license script update. WIP: use Qt test framework. WIP: test for app and login calls. WIP: test for update & cache on disk calls. WIP: tests for mail settings calls. WIP: all client tests. WIP: linter fixes. WIP: fix missing license link. WIP: update dependency_license script for gRPC and protobuf. WIP: removed unused file. WIP: app & login event streaming tests. WIP: update event stream tests. WIP: completed event streaming tests. GODT-1554: qt C++ frontend skeleton. WIP: C++ backend declaration. wip: started drafting user model. WIP: users. not functional. WIP: invokable methods WIP: Exception class + backend 'injection' into QML. WIP: switch to VCPKG to ease multi-arch compilation, C++ RPC client skeleton. WIP: Renaming and reorganisation WIP:introduced new 'grpc' go frontend. WIP: Worker & Oveerseer for thread management. WIP: added log to C++ app. WIP: event stream architecture on Go side. WIP: event parsing and streamer stopping. WIP: Moved grpc to frontend subfolder + use vcpkg for gRPC and protobuf. WIP: windows building ok WIP: wired a few messages WIP: more wiring. WIP: Fixed imports after rebase on top of devel. WIP: wired some bool and string properties. WIP: more properties. WIP: wired cache on disk stuff WIP: connect event watcher. WIP: login WIP: fix showSplashScreen WIP: Wired login calls. WIP: user list. WIP: Refactored main(). WIP: User retrieval . WIP: no shared pointer in user model. WIP: fixed user count. WIP: cached goos. WIP: Wired autostart WIP: beta channel toggle wired. WIP: User removal WIP: wired theme WIP: implemented configure apple mail. WIP: split mode. WIP: fixed user updates. WIP: fixed Quit from tray icon WIP: wired CurrentEmailClient WIP: wired UseSSLForSMTP WIP: wired change ports . WIP: wired DoH. . WIP: wired keychain calls. WIP: wired autoupdate option. WIP: QML Backend clean-up. WIP: cleanup. WIP: moved user related files in subfolder. . WIP: User are managed using smart pointers. WIP: cleanup. WIP: more cleanup. WIP: mail events forwarding WIP: code inspection tweaks from CLion. WIP: moved QML, cleanup, and missing copyright notices. WIP: Backend is not QMLBackend. Other: fixed issues reported by Leander. [skip ci] --- .gitignore | 4 +- COPYING_NOTES.md | 9 +- go.mod | 11 +- go.sum | 16 +- internal/app/bridge/bridge.go | 8 +- internal/frontend/frontend.go | 10 +- .../grpc/bridge.pb.go} | 2476 +-- .../grpc/bridge.proto} | 66 +- internal/frontend/grpc/bridge_grpc.pb.go | 1955 ++ internal/frontend/grpc/certs.go | 69 + internal/frontend/grpc/event_factory.go | 199 + internal/frontend/grpc/service.go | 329 + internal/frontend/grpc/service_methods.go | 543 + internal/frontend/grpc/service_stream.go | 151 + internal/frontend/grpc/service_user.go | 132 + .../frontend/{qt/helpers.go => grpc/utils.go} | 34 +- internal/frontend/qt/frontend.go | 162 - internal/frontend/qt/frontend_events.go | 104 - internal/frontend/qt/frontend_help.go | 68 - internal/frontend/qt/frontend_init.go | 120 - internal/frontend/qt/frontend_nogui.go | 82 - internal/frontend/qt/frontend_settings.go | 218 - internal/frontend/qt/frontend_updates.go | 148 - internal/frontend/qt/frontend_users.go | 196 - internal/frontend/qt/log/log.cpp | 44 - internal/frontend/qt/log/log.go | 47 - internal/frontend/qt/qml_backend.go | 317 - internal/frontend/qt/qml_users.go | 297 - internal/frontend/qt6/AppController.cpp | 45 + internal/frontend/qt6/AppController.h | 59 + internal/frontend/qt6/CMakeLists.txt | 136 + .../DockIcon/DockIcon.cpp} | 16 +- .../{qt/log/log.h => qt6/DockIcon/DockIcon.h} | 19 +- .../DockIcon.m => qt6/DockIcon/DockIcon.mm} | 21 +- internal/frontend/qt6/Doxyfile | 2656 +++ internal/frontend/qt6/EventStreamWorker.cpp | 57 + internal/frontend/qt6/EventStreamWorker.h | 52 + internal/frontend/qt6/Exception.cpp | 68 + internal/frontend/qt6/Exception.h | 46 + internal/frontend/qt6/GRPC/GRPCClient.cpp | 1183 ++ internal/frontend/qt6/GRPC/GRPCClient.h | 214 + internal/frontend/qt6/GRPC/GRPCUtils.cpp | 63 + .../GRPC/GRPCUtils.h} | 22 +- internal/frontend/qt6/GRPC/bridge.grpc.pb.cc | 2179 +++ internal/frontend/qt6/GRPC/bridge.grpc.pb.h | 8146 +++++++++ internal/frontend/qt6/GRPC/bridge.pb.cc | 12646 +++++++++++++ internal/frontend/qt6/GRPC/bridge.pb.h | 14902 ++++++++++++++++ internal/frontend/qt6/Log.cpp | 159 + internal/frontend/qt6/Log.h | 74 + .../{qt/dockicon/DockIcon.h => qt6/Pch.h} | 11 +- internal/frontend/qt6/QMLBackend.cpp | 316 + internal/frontend/qt6/QMLBackend.h | 222 + internal/frontend/qt6/User/User.cpp | 95 + internal/frontend/qt6/User/User.h | 93 + internal/frontend/qt6/User/UserList.cpp | 220 + internal/frontend/qt6/User/UserList.h | 64 + internal/frontend/qt6/Worker/Overseer.cpp | 103 + internal/frontend/qt6/Worker/Overseer.h | 55 + internal/frontend/qt6/Worker/Worker.h | 46 + internal/frontend/qt6/build.sh | 22 + internal/frontend/qt6/main.cpp | 135 + .../{ => qt6}/qml/AccountDelegate.qml | 0 .../frontend/{ => qt6}/qml/AccountView.qml | 0 internal/frontend/{ => qt6}/qml/Banner.qml | 0 internal/frontend/{ => qt6}/qml/Bridge.qml | 0 .../{ => qt6}/qml/BridgeTest/UserControl.qml | 0 .../{ => qt6}/qml/BridgeTest/UserList.qml | 0 .../{ => qt6}/qml/BridgeTest/UserModel.qml | 0 .../frontend/{ => qt6}/qml/Bridge_test.qml | 0 .../frontend/{ => qt6}/qml/BugReportView.qml | 0 .../frontend/{ => qt6}/qml/Configuration.qml | 0 .../{ => qt6}/qml/ConfigurationItem.qml | 0 .../frontend/{ => qt6}/qml/ContentWrapper.qml | 0 .../frontend/{ => qt6}/qml/DebugWrapper.qml | 0 .../{ => qt6}/qml/GeneralSettings.qml | 0 internal/frontend/{ => qt6}/qml/HelpView.qml | 0 .../{ => qt6}/qml/KeychainSettings.qml | 0 .../{ => qt6}/qml/LocalCacheSettings.qml | 0 .../frontend/{ => qt6}/qml/MainWindow.qml | 4 + .../{ => qt6}/qml/NotificationDialog.qml | 0 .../{ => qt6}/qml/NotificationPopups.qml | 0 .../qml/Notifications/Notification.qml | 0 .../qml/Notifications/NotificationFilter.qml | 0 .../qml/Notifications/Notifications.qml | 0 .../{ => qt6}/qml/Notifications/qmldir | 0 .../frontend/{ => qt6}/qml/PortSettings.qml | 0 .../frontend/{ => qt6}/qml/Proton/Action.qml | 0 .../qml/Proton/ApplicationWindow.qml | 0 .../frontend/{ => qt6}/qml/Proton/Button.qml | 0 .../{ => qt6}/qml/Proton/CheckBox.qml | 0 .../{ => qt6}/qml/Proton/ColorScheme.qml | 0 .../{ => qt6}/qml/Proton/ComboBox.qml | 0 .../frontend/{ => qt6}/qml/Proton/Dialog.qml | 0 .../frontend/{ => qt6}/qml/Proton/Label.qml | 0 .../frontend/{ => qt6}/qml/Proton/Menu.qml | 0 .../{ => qt6}/qml/Proton/MenuItem.qml | 0 .../frontend/{ => qt6}/qml/Proton/Popup.qml | 0 .../{ => qt6}/qml/Proton/RadioButton.qml | 0 .../frontend/{ => qt6}/qml/Proton/Style.qml | 0 .../frontend/{ => qt6}/qml/Proton/Switch.qml | 0 .../{ => qt6}/qml/Proton/TextArea.qml | 0 .../{ => qt6}/qml/Proton/TextField.qml | 0 .../frontend/{ => qt6}/qml/Proton/Toggle.qml | 0 internal/frontend/{ => qt6}/qml/Proton/qmldir | 0 .../frontend/{ => qt6}/qml/SMTPSettings.qml | 0 .../frontend/{ => qt6}/qml/SettingsItem.qml | 0 .../frontend/{ => qt6}/qml/SettingsView.qml | 0 .../frontend/{ => qt6}/qml/SetupGuide.qml | 0 internal/frontend/{ => qt6}/qml/SignIn.qml | 0 .../frontend/{ => qt6}/qml/SplashScreen.qml | 0 internal/frontend/{ => qt6}/qml/Status.qml | 0 .../frontend/{ => qt6}/qml/StatusWindow.qml | 0 .../frontend/{ => qt6}/qml/WelcomeGuide.qml | 0 .../{ => qt6}/qml/bridgeqml.qmlproject | 0 .../{ => qt6}/qml/icons/Loader_16.svg | 0 .../{ => qt6}/qml/icons/Loader_48.svg | 0 .../frontend/{ => qt6}/qml/icons/ic-alert.svg | 0 .../{ => qt6}/qml/icons/ic-apple-mail.svg | 0 .../{ => qt6}/qml/icons/ic-arrow-left.svg | 0 .../{ => qt6}/qml/icons/ic-card-identity.svg | 0 .../frontend/{ => qt6}/qml/icons/ic-check.svg | 0 .../{ => qt6}/qml/icons/ic-chevron-down.svg | 0 .../{ => qt6}/qml/icons/ic-chevron-up.svg | 0 .../{ => qt6}/qml/icons/ic-cog-wheel.svg | 0 .../{ => qt6}/qml/icons/ic-connected.svg | 0 .../frontend/{ => qt6}/qml/icons/ic-copy.svg | 0 .../{ => qt6}/qml/icons/ic-cross-close.svg | 0 .../frontend/{ => qt6}/qml/icons/ic-drive.svg | 0 .../icons/ic-exclamation-circle-filled.svg | 0 .../{ => qt6}/qml/icons/ic-external-link.svg | 0 .../{ => qt6}/qml/icons/ic-eye-slash.svg | 0 .../frontend/{ => qt6}/qml/icons/ic-eye.svg | 0 .../icons/ic-illustrative-view-html-code.svg | 0 .../qml/icons/ic-info-circle-filled.svg | 0 .../frontend/{ => qt6}/qml/icons/ic-info.svg | 0 .../qml/icons/ic-microsoft-outlook.svg | 0 .../qml/icons/ic-mozilla-thunderbird.svg | 0 .../{ => qt6}/qml/icons/ic-no-connection.svg | 0 .../qml/icons/ic-other-mail-clients.svg | 0 .../frontend/{ => qt6}/qml/icons/ic-plus.svg | 0 .../qml/icons/ic-question-circle.svg | 0 .../{ => qt6}/qml/icons/ic-success.svg | 0 .../qml/icons/ic-three-dots-vertical.svg | 0 .../frontend/{ => qt6}/qml/icons/ic-trash.svg | 0 .../{ => qt6}/qml/icons/img-proton-logos.png | Bin .../{ => qt6}/qml/icons/img-proton-logos.svg | 0 .../{ => qt6}/qml/icons/img-splash.png | Bin .../{ => qt6}/qml/icons/img-splash.svg | 0 .../{ => qt6}/qml/icons/img-welcome-dark.png | Bin .../{ => qt6}/qml/icons/img-welcome-dark.svg | 0 .../{ => qt6}/qml/icons/img-welcome.png | Bin .../{ => qt6}/qml/icons/img-welcome.svg | 0 .../{ => qt6}/qml/icons/product_logos.svg | 0 .../qml/icons/product_logos_dark.svg | 0 .../qml/icons/systray-color-error.png | Bin .../qml/icons/systray-color-norm.png | Bin .../qml/icons/systray-color-update.png | Bin .../qml/icons/systray-color-warn.png | Bin .../qml/icons/systray-mono-error.png | Bin .../{ => qt6}/qml/icons/systray-mono-norm.png | Bin .../qml/icons/systray-mono-update.png | Bin .../{ => qt6}/qml/icons/systray-mono-warn.png | Bin .../frontend/{ => qt6}/qml/icons/systray.svg | 0 .../frontend/{ => qt6}/qml/tests/Buttons.qml | 0 .../{ => qt6}/qml/tests/ButtonsColumn.qml | 0 .../{ => qt6}/qml/tests/CheckBoxes.qml | 0 .../{ => qt6}/qml/tests/ComboBoxes.qml | 0 .../{ => qt6}/qml/tests/RadioButtons.qml | 0 .../frontend/{ => qt6}/qml/tests/Switches.qml | 0 .../frontend/{ => qt6}/qml/tests/Test.qml | 0 .../{ => qt6}/qml/tests/TestComponents.qml | 0 .../{ => qt6}/qml/tests/TextAreas.qml | 0 .../{ => qt6}/qml/tests/TextFields.qml | 0 internal/rpc/bridge_rpc_grpc.pb.go | 2347 --- internal/rpc/server.go | 121 - internal/rpc/service.go | 690 - test/rpc/client/CMakeLists.txt | 17 +- test/rpc/client/RpcClient.cpp | 31 +- test/rpc/client/RpcClient.h | 5 +- .../bridge.grpc.pb.cc} | 1498 +- .../bridge.grpc.pb.h} | 896 +- .../bridge_rpc.pb.cc => grpc/bridge.pb.cc} | 3126 ++-- .../{rpc/bridge_rpc.pb.h => grpc/bridge.pb.h} | 3490 ++-- 183 files changed, 53334 insertions(+), 10851 deletions(-) rename internal/{rpc/bridge_rpc.pb.go => frontend/grpc/bridge.pb.go} (56%) rename internal/{rpc/bridge_rpc.proto => frontend/grpc/bridge.proto} (86%) create mode 100644 internal/frontend/grpc/bridge_grpc.pb.go create mode 100644 internal/frontend/grpc/certs.go create mode 100644 internal/frontend/grpc/event_factory.go create mode 100644 internal/frontend/grpc/service.go create mode 100644 internal/frontend/grpc/service_methods.go create mode 100644 internal/frontend/grpc/service_stream.go create mode 100644 internal/frontend/grpc/service_user.go rename internal/frontend/{qt/helpers.go => grpc/utils.go} (70%) delete mode 100644 internal/frontend/qt/frontend.go delete mode 100644 internal/frontend/qt/frontend_events.go delete mode 100644 internal/frontend/qt/frontend_help.go delete mode 100644 internal/frontend/qt/frontend_init.go delete mode 100644 internal/frontend/qt/frontend_nogui.go delete mode 100644 internal/frontend/qt/frontend_settings.go delete mode 100644 internal/frontend/qt/frontend_updates.go delete mode 100644 internal/frontend/qt/frontend_users.go delete mode 100644 internal/frontend/qt/log/log.cpp delete mode 100644 internal/frontend/qt/log/log.go delete mode 100644 internal/frontend/qt/qml_backend.go delete mode 100644 internal/frontend/qt/qml_users.go create mode 100644 internal/frontend/qt6/AppController.cpp create mode 100644 internal/frontend/qt6/AppController.h create mode 100644 internal/frontend/qt6/CMakeLists.txt rename internal/frontend/{qt/dockicon/dockicon_default.go => qt6/DockIcon/DockIcon.cpp} (81%) rename internal/frontend/{qt/log/log.h => qt6/DockIcon/DockIcon.h} (74%) rename internal/frontend/{qt/dockicon/DockIcon.m => qt6/DockIcon/DockIcon.mm} (86%) create mode 100644 internal/frontend/qt6/Doxyfile create mode 100644 internal/frontend/qt6/EventStreamWorker.cpp create mode 100644 internal/frontend/qt6/EventStreamWorker.h create mode 100644 internal/frontend/qt6/Exception.cpp create mode 100644 internal/frontend/qt6/Exception.h create mode 100644 internal/frontend/qt6/GRPC/GRPCClient.cpp create mode 100644 internal/frontend/qt6/GRPC/GRPCClient.h create mode 100644 internal/frontend/qt6/GRPC/GRPCUtils.cpp rename internal/frontend/{qt/dockicon/dockicon_darwin.go => qt6/GRPC/GRPCUtils.h} (65%) create mode 100644 internal/frontend/qt6/GRPC/bridge.grpc.pb.cc create mode 100644 internal/frontend/qt6/GRPC/bridge.grpc.pb.h create mode 100644 internal/frontend/qt6/GRPC/bridge.pb.cc create mode 100644 internal/frontend/qt6/GRPC/bridge.pb.h create mode 100644 internal/frontend/qt6/Log.cpp create mode 100644 internal/frontend/qt6/Log.h rename internal/frontend/{qt/dockicon/DockIcon.h => qt6/Pch.h} (84%) create mode 100644 internal/frontend/qt6/QMLBackend.cpp create mode 100644 internal/frontend/qt6/QMLBackend.h create mode 100644 internal/frontend/qt6/User/User.cpp create mode 100644 internal/frontend/qt6/User/User.h create mode 100644 internal/frontend/qt6/User/UserList.cpp create mode 100644 internal/frontend/qt6/User/UserList.h create mode 100644 internal/frontend/qt6/Worker/Overseer.cpp create mode 100644 internal/frontend/qt6/Worker/Overseer.h create mode 100644 internal/frontend/qt6/Worker/Worker.h create mode 100755 internal/frontend/qt6/build.sh create mode 100644 internal/frontend/qt6/main.cpp rename internal/frontend/{ => qt6}/qml/AccountDelegate.qml (100%) rename internal/frontend/{ => qt6}/qml/AccountView.qml (100%) rename internal/frontend/{ => qt6}/qml/Banner.qml (100%) rename internal/frontend/{ => qt6}/qml/Bridge.qml (100%) rename internal/frontend/{ => qt6}/qml/BridgeTest/UserControl.qml (100%) rename internal/frontend/{ => qt6}/qml/BridgeTest/UserList.qml (100%) rename internal/frontend/{ => qt6}/qml/BridgeTest/UserModel.qml (100%) rename internal/frontend/{ => qt6}/qml/Bridge_test.qml (100%) rename internal/frontend/{ => qt6}/qml/BugReportView.qml (100%) rename internal/frontend/{ => qt6}/qml/Configuration.qml (100%) rename internal/frontend/{ => qt6}/qml/ConfigurationItem.qml (100%) rename internal/frontend/{ => qt6}/qml/ContentWrapper.qml (100%) rename internal/frontend/{ => qt6}/qml/DebugWrapper.qml (100%) rename internal/frontend/{ => qt6}/qml/GeneralSettings.qml (100%) rename internal/frontend/{ => qt6}/qml/HelpView.qml (100%) rename internal/frontend/{ => qt6}/qml/KeychainSettings.qml (100%) rename internal/frontend/{ => qt6}/qml/LocalCacheSettings.qml (100%) rename internal/frontend/{ => qt6}/qml/MainWindow.qml (99%) rename internal/frontend/{ => qt6}/qml/NotificationDialog.qml (100%) rename internal/frontend/{ => qt6}/qml/NotificationPopups.qml (100%) rename internal/frontend/{ => qt6}/qml/Notifications/Notification.qml (100%) rename internal/frontend/{ => qt6}/qml/Notifications/NotificationFilter.qml (100%) rename internal/frontend/{ => qt6}/qml/Notifications/Notifications.qml (100%) rename internal/frontend/{ => qt6}/qml/Notifications/qmldir (100%) rename internal/frontend/{ => qt6}/qml/PortSettings.qml (100%) rename internal/frontend/{ => qt6}/qml/Proton/Action.qml (100%) rename internal/frontend/{ => qt6}/qml/Proton/ApplicationWindow.qml (100%) rename internal/frontend/{ => qt6}/qml/Proton/Button.qml (100%) rename internal/frontend/{ => qt6}/qml/Proton/CheckBox.qml (100%) rename internal/frontend/{ => qt6}/qml/Proton/ColorScheme.qml (100%) rename internal/frontend/{ => qt6}/qml/Proton/ComboBox.qml (100%) rename internal/frontend/{ => qt6}/qml/Proton/Dialog.qml (100%) rename internal/frontend/{ => qt6}/qml/Proton/Label.qml (100%) rename internal/frontend/{ => qt6}/qml/Proton/Menu.qml (100%) rename internal/frontend/{ => qt6}/qml/Proton/MenuItem.qml (100%) rename internal/frontend/{ => qt6}/qml/Proton/Popup.qml (100%) rename internal/frontend/{ => qt6}/qml/Proton/RadioButton.qml (100%) rename internal/frontend/{ => qt6}/qml/Proton/Style.qml (100%) rename internal/frontend/{ => qt6}/qml/Proton/Switch.qml (100%) rename internal/frontend/{ => qt6}/qml/Proton/TextArea.qml (100%) rename internal/frontend/{ => qt6}/qml/Proton/TextField.qml (100%) rename internal/frontend/{ => qt6}/qml/Proton/Toggle.qml (100%) rename internal/frontend/{ => qt6}/qml/Proton/qmldir (100%) rename internal/frontend/{ => qt6}/qml/SMTPSettings.qml (100%) rename internal/frontend/{ => qt6}/qml/SettingsItem.qml (100%) rename internal/frontend/{ => qt6}/qml/SettingsView.qml (100%) rename internal/frontend/{ => qt6}/qml/SetupGuide.qml (100%) rename internal/frontend/{ => qt6}/qml/SignIn.qml (100%) rename internal/frontend/{ => qt6}/qml/SplashScreen.qml (100%) rename internal/frontend/{ => qt6}/qml/Status.qml (100%) rename internal/frontend/{ => qt6}/qml/StatusWindow.qml (100%) rename internal/frontend/{ => qt6}/qml/WelcomeGuide.qml (100%) rename internal/frontend/{ => qt6}/qml/bridgeqml.qmlproject (100%) rename internal/frontend/{ => qt6}/qml/icons/Loader_16.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/Loader_48.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/ic-alert.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/ic-apple-mail.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/ic-arrow-left.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/ic-card-identity.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/ic-check.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/ic-chevron-down.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/ic-chevron-up.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/ic-cog-wheel.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/ic-connected.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/ic-copy.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/ic-cross-close.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/ic-drive.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/ic-exclamation-circle-filled.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/ic-external-link.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/ic-eye-slash.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/ic-eye.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/ic-illustrative-view-html-code.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/ic-info-circle-filled.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/ic-info.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/ic-microsoft-outlook.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/ic-mozilla-thunderbird.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/ic-no-connection.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/ic-other-mail-clients.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/ic-plus.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/ic-question-circle.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/ic-success.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/ic-three-dots-vertical.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/ic-trash.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/img-proton-logos.png (100%) rename internal/frontend/{ => qt6}/qml/icons/img-proton-logos.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/img-splash.png (100%) rename internal/frontend/{ => qt6}/qml/icons/img-splash.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/img-welcome-dark.png (100%) rename internal/frontend/{ => qt6}/qml/icons/img-welcome-dark.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/img-welcome.png (100%) rename internal/frontend/{ => qt6}/qml/icons/img-welcome.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/product_logos.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/product_logos_dark.svg (100%) rename internal/frontend/{ => qt6}/qml/icons/systray-color-error.png (100%) rename internal/frontend/{ => qt6}/qml/icons/systray-color-norm.png (100%) rename internal/frontend/{ => qt6}/qml/icons/systray-color-update.png (100%) rename internal/frontend/{ => qt6}/qml/icons/systray-color-warn.png (100%) rename internal/frontend/{ => qt6}/qml/icons/systray-mono-error.png (100%) rename internal/frontend/{ => qt6}/qml/icons/systray-mono-norm.png (100%) rename internal/frontend/{ => qt6}/qml/icons/systray-mono-update.png (100%) rename internal/frontend/{ => qt6}/qml/icons/systray-mono-warn.png (100%) rename internal/frontend/{ => qt6}/qml/icons/systray.svg (100%) rename internal/frontend/{ => qt6}/qml/tests/Buttons.qml (100%) rename internal/frontend/{ => qt6}/qml/tests/ButtonsColumn.qml (100%) rename internal/frontend/{ => qt6}/qml/tests/CheckBoxes.qml (100%) rename internal/frontend/{ => qt6}/qml/tests/ComboBoxes.qml (100%) rename internal/frontend/{ => qt6}/qml/tests/RadioButtons.qml (100%) rename internal/frontend/{ => qt6}/qml/tests/Switches.qml (100%) rename internal/frontend/{ => qt6}/qml/tests/Test.qml (100%) rename internal/frontend/{ => qt6}/qml/tests/TestComponents.qml (100%) rename internal/frontend/{ => qt6}/qml/tests/TextAreas.qml (100%) rename internal/frontend/{ => qt6}/qml/tests/TextFields.qml (100%) delete mode 100644 internal/rpc/bridge_rpc_grpc.pb.go delete mode 100644 internal/rpc/server.go delete mode 100644 internal/rpc/service.go rename test/rpc/client/{rpc/bridge_rpc.grpc.pb.cc => grpc/bridge.grpc.pb.cc} (58%) rename test/rpc/client/{rpc/bridge_rpc.grpc.pb.h => grpc/bridge.grpc.pb.h} (92%) rename test/rpc/client/{rpc/bridge_rpc.pb.cc => grpc/bridge.pb.cc} (75%) rename test/rpc/client/{rpc/bridge_rpc.pb.h => grpc/bridge.pb.h} (76%) diff --git a/.gitignore b/.gitignore index 8fda6e0f..897ac864 100644 --- a/.gitignore +++ b/.gitignore @@ -34,4 +34,6 @@ proton-bridge # Jetbrains (CLion, Golang) cmake build dirs cmake-build-*/ -cmake-build-*/ + +# Doxygen doc files +_doc/ diff --git a/COPYING_NOTES.md b/COPYING_NOTES.md index 66e557c0..d6d23a55 100644 --- a/COPYING_NOTES.md +++ b/COPYING_NOTES.md @@ -33,12 +33,10 @@ Proton Mail Bridge includes the following 3rd party software: * [go-srp](https://github.com/ProtonMail/go-srp) available under [license](https://github.com/ProtonMail/go-srp/blob/master/LICENSE) * [go-vcard](https://github.com/ProtonMail/go-vcard) available under [license](https://github.com/ProtonMail/go-vcard/blob/master/LICENSE) * [gopenpgp](https://github.com/ProtonMail/gopenpgp/v2) available under [license](https://github.com/ProtonMail/gopenpgp/v2/blob/master/LICENSE) +* [proton-bridge](https://github.com/ProtonMail/proton-bridge) available under [license](https://github.com/ProtonMail/proton-bridge/blob/master/LICENSE) * [goquery](https://github.com/PuerkitoBio/goquery) available under [license](https://github.com/PuerkitoBio/goquery/blob/master/LICENSE) * [ishell](https://github.com/abiosoft/ishell) available under [license](https://github.com/abiosoft/ishell/blob/master/LICENSE) -* [readline](https://github.com/abiosoft/readline) available under [license](https://github.com/abiosoft/readline/blob/master/LICENSE) * [go-singleinstance](https://github.com/allan-simon/go-singleinstance) available under [license](https://github.com/allan-simon/go-singleinstance/blob/master/LICENSE) -* [logex](https://github.com/chzyer/logex) available under [license](https://github.com/chzyer/logex/blob/master/LICENSE) -* [test](https://github.com/chzyer/test) available under [license](https://github.com/chzyer/test/blob/master/LICENSE) * [godog](https://github.com/cucumber/godog) available under [license](https://github.com/cucumber/godog/blob/master/LICENSE) * [messages-go](https://github.com/cucumber/messages-go/v16) available under [license](https://github.com/cucumber/messages-go/v16/blob/master/LICENSE) * [go-sysinfo](https://github.com/elastic/go-sysinfo) available under [license](https://github.com/elastic/go-sysinfo/blob/master/LICENSE) @@ -51,9 +49,7 @@ Proton Mail Bridge includes the following 3rd party software: * [go-sasl](https://github.com/emersion/go-sasl) available under [license](https://github.com/emersion/go-sasl/blob/master/LICENSE) * [go-smtp](https://github.com/emersion/go-smtp) available under [license](https://github.com/emersion/go-smtp/blob/master/LICENSE) * [go-textwrapper](https://github.com/emersion/go-textwrapper) available under [license](https://github.com/emersion/go-textwrapper/blob/master/LICENSE) -* [go-vcard](https://github.com/emersion/go-vcard) available under [license](https://github.com/emersion/go-vcard/blob/master/LICENSE) * [color](https://github.com/fatih/color) available under [license](https://github.com/fatih/color/blob/master/LICENSE) -* [go-shlex](https://github.com/flynn-archive/go-shlex) available under [license](https://github.com/flynn-archive/go-shlex/blob/master/LICENSE) * [sentry-go](https://github.com/getsentry/sentry-go) available under [license](https://github.com/getsentry/sentry-go/blob/master/LICENSE) * [resty](https://github.com/go-resty/resty/v2) available under [license](https://github.com/go-resty/resty/v2/blob/master/LICENSE) * [dbus](https://github.com/godbus/dbus) available under [license](https://github.com/godbus/dbus/blob/master/LICENSE) @@ -66,15 +62,12 @@ Proton Mail Bridge includes the following 3rd party software: * [go-keychain](https://github.com/keybase/go-keychain) available under [license](https://github.com/keybase/go-keychain/blob/master/LICENSE) * [text](https://github.com/kr/text) available under [license](https://github.com/kr/text/blob/master/LICENSE) * [aurora](https://github.com/logrusorgru/aurora) available under [license](https://github.com/logrusorgru/aurora/blob/master/LICENSE) -* [go-runewidth](https://github.com/mattn/go-runewidth) available under [license](https://github.com/mattn/go-runewidth/blob/master/LICENSE) * [dns](https://github.com/miekg/dns) available under [license](https://github.com/miekg/dns/blob/master/LICENSE) * [jsondiff](https://github.com/nsf/jsondiff) available under [license](https://github.com/nsf/jsondiff/blob/master/LICENSE) -* [tablewriter](https://github.com/olekukonko/tablewriter) available under [license](https://github.com/olekukonko/tablewriter/blob/master/LICENSE) * [errors](https://github.com/pkg/errors) available under [license](https://github.com/pkg/errors/blob/master/LICENSE) * [procfs](https://github.com/prometheus/procfs) available under [license](https://github.com/prometheus/procfs/blob/master/LICENSE) * [du](https://github.com/ricochet2200/go-disk-usage/du) available under [license](https://github.com/ricochet2200/go-disk-usage/du/blob/master/LICENSE) * [logrus](https://github.com/sirupsen/logrus) available under [license](https://github.com/sirupsen/logrus/blob/master/LICENSE) -* [bom](https://github.com/ssor/bom) available under [license](https://github.com/ssor/bom/blob/master/LICENSE) * [testify](https://github.com/stretchr/testify) available under [license](https://github.com/stretchr/testify/blob/master/LICENSE) * [qt](https://github.com/therecipe/qt) available under [license](https://github.com/therecipe/qt/blob/master/LICENSE) * [cli](https://github.com/urfave/cli/v2) available under [license](https://github.com/urfave/cli/v2/blob/master/LICENSE) diff --git a/go.mod b/go.mod index 9b0b1a46..d2b75264 100644 --- a/go.mod +++ b/go.mod @@ -20,12 +20,10 @@ require ( github.com/ProtonMail/go-srp v0.0.5 github.com/ProtonMail/go-vcard v0.0.0-20180326232728-33aaa0a0c8a5 github.com/ProtonMail/gopenpgp/v2 v2.4.7 + github.com/ProtonMail/proton-bridge v1.8.12 github.com/PuerkitoBio/goquery v1.5.1 github.com/abiosoft/ishell v2.0.0+incompatible - github.com/abiosoft/readline v0.0.0-20180607040430-155bce2042db // indirect github.com/allan-simon/go-singleinstance v0.0.0-20160830203053-79edcfdc2dfc - github.com/chzyer/logex v1.1.10 // indirect - github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 // indirect github.com/cucumber/godog v0.12.1 github.com/cucumber/messages-go/v16 v16.0.1 github.com/elastic/go-sysinfo v1.7.1 @@ -38,9 +36,7 @@ require ( github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21 github.com/emersion/go-smtp v0.14.0 github.com/emersion/go-textwrapper v0.0.0-20200911093747-65d896831594 - github.com/emersion/go-vcard v0.0.0-20190105225839-8856043f13c5 // indirect github.com/fatih/color v1.9.0 - github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect github.com/getsentry/sentry-go v0.12.0 github.com/go-resty/resty/v2 v2.6.0 github.com/godbus/dbus v4.1.0+incompatible @@ -53,15 +49,12 @@ require ( github.com/keybase/go-keychain v0.0.0 github.com/kr/text v0.2.0 // indirect github.com/logrusorgru/aurora v2.0.3+incompatible - github.com/mattn/go-runewidth v0.0.9 // indirect github.com/miekg/dns v1.1.41 github.com/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce - github.com/olekukonko/tablewriter v0.0.4 // indirect github.com/pkg/errors v0.9.1 github.com/prometheus/procfs v0.7.3 // indirect github.com/ricochet2200/go-disk-usage/du v0.0.0-20210707232629-ac9918953285 github.com/sirupsen/logrus v1.7.0 - github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect github.com/stretchr/testify v1.7.0 github.com/therecipe/qt v0.0.0-20200701200531-7f61353ee73e github.com/urfave/cli/v2 v2.2.0 @@ -73,7 +66,7 @@ require ( golang.org/x/text v0.3.7 google.golang.org/grpc v1.46.2 google.golang.org/protobuf v1.28.0 - howett.net/plist v1.0.0 + howett.net/plist v1.0.0 // indirect ) replace ( diff --git a/go.sum b/go.sum index 5ccd1f69..60cde0e9 100644 --- a/go.sum +++ b/go.sum @@ -31,6 +31,8 @@ github.com/ProtonMail/docker-credential-helpers v1.1.0/go.mod h1:mK0aBveCxhnQ756 github.com/ProtonMail/go-autostart v0.0.0-20181114175602-c5272053443a h1:fXK2KsfnkBV9Nh+9SKzHchYjuE9s0vI20JG1mbtEAcc= github.com/ProtonMail/go-autostart v0.0.0-20181114175602-c5272053443a/go.mod h1:oTGdE7/DlWIr23G0IKW3OXK9wZ5Hw1GGiaJFccTvZi4= github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= +github.com/ProtonMail/go-crypto v0.0.0-20210512092938-c05353c2d58c/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= +github.com/ProtonMail/go-crypto v0.0.0-20210707164159-52430bf6b52c/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= github.com/ProtonMail/go-crypto v0.0.0-20211221144345-a4f6767435ab h1:5FiL/TCaiKCss/BLMIACDxxadYrx767l9kh0qYX+sLQ= github.com/ProtonMail/go-crypto v0.0.0-20211221144345-a4f6767435ab/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= github.com/ProtonMail/go-crypto v0.0.0-20220113124808-70ae35bab23f/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= @@ -54,8 +56,11 @@ github.com/ProtonMail/go-srp v0.0.5 h1:xhUioxZgDbCnpo9JehyFhwwsn9JLWkUGfB0oiKXgi github.com/ProtonMail/go-srp v0.0.5/go.mod h1:06iYHtLXW8vjLtccWj++x3MKy65sIT8yZd7nrJF49rs= github.com/ProtonMail/go-vcard v0.0.0-20180326232728-33aaa0a0c8a5 h1:Uga1DHFN4GUxuDQr0F71tpi8I9HqPIlZodZAI1lR6VQ= github.com/ProtonMail/go-vcard v0.0.0-20180326232728-33aaa0a0c8a5/go.mod h1:oeP9CMN+ajWp5jKp1kue5daJNwMMxLF+ujPaUIoJWlA= +github.com/ProtonMail/gopenpgp/v2 v2.2.2/go.mod h1:ajUlBGvxMH1UBZnaYO3d1FSVzjiC6kK9XlZYGiDCvpM= github.com/ProtonMail/gopenpgp/v2 v2.4.1 h1:b3El0zabaKi73u4sRnb3hOOUczuKuYpN8wnp7wRsZSc= github.com/ProtonMail/gopenpgp/v2 v2.4.1/go.mod h1:RFjoVjfhV8f78tjz/fLrp/OXkugL3QmWsiJq/fsQYA4= +github.com/ProtonMail/proton-bridge v1.8.12 h1:wR/WguXfVT2qiL+4xcSIlN1XqH49zl81hD0CdVnQdfw= +github.com/ProtonMail/proton-bridge v1.8.12/go.mod h1:ZeGTC11l/KTGLP5aASnS7dxu3T1z5HORA048DpwbVoI= github.com/ProtonMail/gopenpgp/v2 v2.4.7 h1:V3xeelvXgJiZXZuPtSSE+uYbtPw4RmbmyPqXDAESPhg= github.com/ProtonMail/gopenpgp/v2 v2.4.7/go.mod h1:ZW1KxHNG6q5LMgFKf9Ap/d2eVYeyGf5+fAUEAjJWtmo= github.com/PuerkitoBio/goquery v1.5.1 h1:PSPBGne8NIUWw+/7vFBV+kG2J/5MOjbzc7154OaKCSE= @@ -150,6 +155,7 @@ github.com/emersion/go-imap-quota v0.0.0-20210203125329-619074823f3c h1:khcEdu1y github.com/emersion/go-imap-quota v0.0.0-20210203125329-619074823f3c/go.mod h1:iApyhIQBiU4XFyr+3kdJyyGqle82TbQyuP2o+OZHrV0= github.com/emersion/go-imap-unselect v0.0.0-20171113212723-b985794e5f26 h1:FiSb8+XBQQSkcX3ubr+1tAtlRJBYaFmRZqOAweZ9Wy8= github.com/emersion/go-imap-unselect v0.0.0-20171113212723-b985794e5f26/go.mod h1:+gnnZx3Mg3MnCzZrv0eZdp5puxXQUgGT/6N6L7ShKfM= +github.com/emersion/go-mbox v1.0.2/go.mod h1:Yp9IVuuOYLEuMv4yjgDHvhb5mHOcYH6x92Oas3QqEZI= github.com/emersion/go-sasl v0.0.0-20191210011802-430746ea8b9b/go.mod h1:G/dpzLu16WtQpBfQ/z3LYiYJn3ZhKSGWn83fyoyQe/k= github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21 h1:OJyUGMJTzHTd1XQp98QTaHernxMYzRaOasRir9hUlFQ= github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ= @@ -175,6 +181,7 @@ github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BMXYYRWT github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:rZfgFAXFS/z/lEd6LJmf9HVZ1LkgYiHx5pHhV5DR16M= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= +github.com/getsentry/sentry-go v0.8.0/go.mod h1:kELm/9iCblqUYh+ZRML7PNdCvEuw24wBvJPYyi86cws= github.com/getsentry/sentry-go v0.12.0 h1:era7g0re5iY13bHSdN/xMkyV+5zZppjRVQhZrXCaEIk= github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -231,6 +238,7 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= @@ -241,13 +249,15 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20190411002643-bd77b112433e h1:XWcjeEtTFTOVA9Fs1w7n2XBftk5ib4oZrhzWk0B+3eA= github.com/gopherjs/gopherjs v0.0.0-20190411002643-bd77b112433e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= +github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= @@ -328,6 +338,7 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= @@ -429,6 +440,7 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= @@ -461,6 +473,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/therecipe/qt v0.0.0-20200701200531-7f61353ee73e h1:G0DQ/TRQyrEZjtLlLwevFjaRiG8eeCMlq9WXQ2OO2bk= github.com/therecipe/qt v0.0.0-20200701200531-7f61353ee73e/go.mod h1:SUUR2j3aE1z6/g76SdD6NwACEpvCxb3fvG82eKbD6us= +github.com/therecipe/qt/internal/binding/files/docs/5.12.0 v0.0.0-20200904063919-c0c124a5770d/go.mod h1:7m8PDYDEtEVqfjoUQc2UrFqhG0CDmoVJjRlQxexndFc= +github.com/therecipe/qt/internal/binding/files/docs/5.13.0 v0.0.0-20200904063919-c0c124a5770d/go.mod h1:mH55Ek7AZcdns5KPp99O0bg+78el64YCYWHiQKrOdt4= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= diff --git a/internal/app/bridge/bridge.go b/internal/app/bridge/bridge.go index c821dd03..5a044e02 100644 --- a/internal/app/bridge/bridge.go +++ b/internal/app/bridge/bridge.go @@ -31,7 +31,6 @@ import ( "github.com/ProtonMail/proton-bridge/v2/internal/frontend" "github.com/ProtonMail/proton-bridge/v2/internal/frontend/types" "github.com/ProtonMail/proton-bridge/v2/internal/imap" - "github.com/ProtonMail/proton-bridge/v2/internal/rpc" "github.com/ProtonMail/proton-bridge/v2/internal/smtp" "github.com/ProtonMail/proton-bridge/v2/internal/store" "github.com/ProtonMail/proton-bridge/v2/internal/store/cache" @@ -139,11 +138,6 @@ func mailLoop(b *base.Base, c *cli.Context) error { //nolint:funlen smtpPort, useSSL, tlsConfig, smtpBackend, b.Listener).ListenAndServe() }() - go func() { - defer b.CrashHandler.HandlePanic() - rpc.NewServer().ListenAndServe() - }() - // We want to remove old versions if the app exits successfully. b.AddTeardownAction(b.Versioner.RemoveOldVersions) @@ -158,7 +152,7 @@ func mailLoop(b *base.Base, c *cli.Context) error { //nolint:funlen case c.Bool(flagNonInteractive): return <-(make(chan error)) // Block forever. default: - frontendMode = "qt" + frontendMode = "grpc" } f := frontend.New( diff --git a/internal/frontend/frontend.go b/internal/frontend/frontend.go index a69aa6b6..964d5687 100644 --- a/internal/frontend/frontend.go +++ b/internal/frontend/frontend.go @@ -23,7 +23,7 @@ import ( "github.com/ProtonMail/proton-bridge/v2/internal/config/settings" "github.com/ProtonMail/proton-bridge/v2/internal/config/useragent" "github.com/ProtonMail/proton-bridge/v2/internal/frontend/cli" - "github.com/ProtonMail/proton-bridge/v2/internal/frontend/qt" + "github.com/ProtonMail/proton-bridge/v2/internal/frontend/grpc" "github.com/ProtonMail/proton-bridge/v2/internal/frontend/types" "github.com/ProtonMail/proton-bridge/v2/internal/locations" "github.com/ProtonMail/proton-bridge/v2/internal/updater" @@ -39,7 +39,7 @@ type Frontend interface { WaitUntilFrontendIsReady() } -// New returns initialized frontend based on `frontendType`, which can be `cli` or `qt`. +// New returns initialized frontend based on `frontendType`, which can be `cli` or `grpc`. func New( version, buildVersion, @@ -58,10 +58,9 @@ func New( ) Frontend { bridgeWrap := types.NewBridgeWrap(bridge) switch frontendType { - case "qt": - return qt.New( + case "grpc": + return grpc.NewService( version, - buildVersion, programName, showWindowOnStart, panicHandler, @@ -74,6 +73,7 @@ func New( noEncConfirmator, restarter, ) + case "cli": return cli.New( panicHandler, diff --git a/internal/rpc/bridge_rpc.pb.go b/internal/frontend/grpc/bridge.pb.go similarity index 56% rename from internal/rpc/bridge_rpc.pb.go rename to internal/frontend/grpc/bridge.pb.go index 9d4ff400..bf3c282c 100644 --- a/internal/rpc/bridge_rpc.pb.go +++ b/internal/frontend/grpc/bridge.pb.go @@ -19,9 +19,9 @@ // versions: // protoc-gen-go v1.28.0 // protoc v3.19.4 -// source: bridge_rpc.proto +// source: bridge.proto -package rpc +package grpc import ( protoreflect "google.golang.org/protobuf/reflect/protoreflect" @@ -84,11 +84,11 @@ func (x LoginErrorType) String() string { } func (LoginErrorType) Descriptor() protoreflect.EnumDescriptor { - return file_bridge_rpc_proto_enumTypes[0].Descriptor() + return file_bridge_proto_enumTypes[0].Descriptor() } func (LoginErrorType) Type() protoreflect.EnumType { - return &file_bridge_rpc_proto_enumTypes[0] + return &file_bridge_proto_enumTypes[0] } func (x LoginErrorType) Number() protoreflect.EnumNumber { @@ -97,7 +97,7 @@ func (x LoginErrorType) Number() protoreflect.EnumNumber { // Deprecated: Use LoginErrorType.Descriptor instead. func (LoginErrorType) EnumDescriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{0} + return file_bridge_proto_rawDescGZIP(), []int{0} } type UpdateErrorType int32 @@ -133,11 +133,11 @@ func (x UpdateErrorType) String() string { } func (UpdateErrorType) Descriptor() protoreflect.EnumDescriptor { - return file_bridge_rpc_proto_enumTypes[1].Descriptor() + return file_bridge_proto_enumTypes[1].Descriptor() } func (UpdateErrorType) Type() protoreflect.EnumType { - return &file_bridge_rpc_proto_enumTypes[1] + return &file_bridge_proto_enumTypes[1] } func (x UpdateErrorType) Number() protoreflect.EnumNumber { @@ -146,7 +146,7 @@ func (x UpdateErrorType) Number() protoreflect.EnumNumber { // Deprecated: Use UpdateErrorType.Descriptor instead. func (UpdateErrorType) EnumDescriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{1} + return file_bridge_proto_rawDescGZIP(), []int{1} } type CacheErrorType int32 @@ -182,11 +182,11 @@ func (x CacheErrorType) String() string { } func (CacheErrorType) Descriptor() protoreflect.EnumDescriptor { - return file_bridge_rpc_proto_enumTypes[2].Descriptor() + return file_bridge_proto_enumTypes[2].Descriptor() } func (CacheErrorType) Type() protoreflect.EnumType { - return &file_bridge_rpc_proto_enumTypes[2] + return &file_bridge_proto_enumTypes[2] } func (x CacheErrorType) Number() protoreflect.EnumNumber { @@ -195,7 +195,7 @@ func (x CacheErrorType) Number() protoreflect.EnumNumber { // Deprecated: Use CacheErrorType.Descriptor instead. func (CacheErrorType) EnumDescriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{2} + return file_bridge_proto_rawDescGZIP(), []int{2} } type MailSettingsErrorType int32 @@ -228,11 +228,11 @@ func (x MailSettingsErrorType) String() string { } func (MailSettingsErrorType) Descriptor() protoreflect.EnumDescriptor { - return file_bridge_rpc_proto_enumTypes[3].Descriptor() + return file_bridge_proto_enumTypes[3].Descriptor() } func (MailSettingsErrorType) Type() protoreflect.EnumType { - return &file_bridge_rpc_proto_enumTypes[3] + return &file_bridge_proto_enumTypes[3] } func (x MailSettingsErrorType) Number() protoreflect.EnumNumber { @@ -241,65 +241,7 @@ func (x MailSettingsErrorType) Number() protoreflect.EnumNumber { // Deprecated: Use MailSettingsErrorType.Descriptor instead. func (MailSettingsErrorType) EnumDescriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{3} -} - -//********************************************************** -// GUI related messages -//********************************************************** -type PointResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - X int32 `protobuf:"varint,1,opt,name=x,proto3" json:"x,omitempty"` - Y int32 `protobuf:"varint,2,opt,name=y,proto3" json:"y,omitempty"` -} - -func (x *PointResponse) Reset() { - *x = PointResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PointResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PointResponse) ProtoMessage() {} - -func (x *PointResponse) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PointResponse.ProtoReflect.Descriptor instead. -func (*PointResponse) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{0} -} - -func (x *PointResponse) GetX() int32 { - if x != nil { - return x.X - } - return 0 -} - -func (x *PointResponse) GetY() int32 { - if x != nil { - return x.Y - } - return 0 + return file_bridge_proto_rawDescGZIP(), []int{3} } type ReportBugRequest struct { @@ -316,7 +258,7 @@ type ReportBugRequest struct { func (x *ReportBugRequest) Reset() { *x = ReportBugRequest{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[1] + mi := &file_bridge_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -329,7 +271,7 @@ func (x *ReportBugRequest) String() string { func (*ReportBugRequest) ProtoMessage() {} func (x *ReportBugRequest) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[1] + mi := &file_bridge_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -342,7 +284,7 @@ func (x *ReportBugRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportBugRequest.ProtoReflect.Descriptor instead. func (*ReportBugRequest) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{1} + return file_bridge_proto_rawDescGZIP(), []int{0} } func (x *ReportBugRequest) GetDescription() string { @@ -385,7 +327,7 @@ type LoginRequest struct { func (x *LoginRequest) Reset() { *x = LoginRequest{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[2] + mi := &file_bridge_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -398,7 +340,7 @@ func (x *LoginRequest) String() string { func (*LoginRequest) ProtoMessage() {} func (x *LoginRequest) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[2] + mi := &file_bridge_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -411,7 +353,7 @@ func (x *LoginRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use LoginRequest.ProtoReflect.Descriptor instead. func (*LoginRequest) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{2} + return file_bridge_proto_rawDescGZIP(), []int{1} } func (x *LoginRequest) GetUsername() string { @@ -439,7 +381,7 @@ type LoginAbortRequest struct { func (x *LoginAbortRequest) Reset() { *x = LoginAbortRequest{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[3] + mi := &file_bridge_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -452,7 +394,7 @@ func (x *LoginAbortRequest) String() string { func (*LoginAbortRequest) ProtoMessage() {} func (x *LoginAbortRequest) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[3] + mi := &file_bridge_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -465,7 +407,7 @@ func (x *LoginAbortRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use LoginAbortRequest.ProtoReflect.Descriptor instead. func (*LoginAbortRequest) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{3} + return file_bridge_proto_rawDescGZIP(), []int{2} } func (x *LoginAbortRequest) GetUsername() string { @@ -490,7 +432,7 @@ type ChangeLocalCacheRequest struct { func (x *ChangeLocalCacheRequest) Reset() { *x = ChangeLocalCacheRequest{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[4] + mi := &file_bridge_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -503,7 +445,7 @@ func (x *ChangeLocalCacheRequest) String() string { func (*ChangeLocalCacheRequest) ProtoMessage() {} func (x *ChangeLocalCacheRequest) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[4] + mi := &file_bridge_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -516,7 +458,7 @@ func (x *ChangeLocalCacheRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ChangeLocalCacheRequest.ProtoReflect.Descriptor instead. func (*ChangeLocalCacheRequest) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{4} + return file_bridge_proto_rawDescGZIP(), []int{3} } func (x *ChangeLocalCacheRequest) GetEnableDiskCache() bool { @@ -548,7 +490,7 @@ type ChangePortsRequest struct { func (x *ChangePortsRequest) Reset() { *x = ChangePortsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[5] + mi := &file_bridge_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -561,7 +503,7 @@ func (x *ChangePortsRequest) String() string { func (*ChangePortsRequest) ProtoMessage() {} func (x *ChangePortsRequest) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[5] + mi := &file_bridge_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -574,7 +516,7 @@ func (x *ChangePortsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ChangePortsRequest.ProtoReflect.Descriptor instead. func (*ChangePortsRequest) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{5} + return file_bridge_proto_rawDescGZIP(), []int{4} } func (x *ChangePortsRequest) GetImapPort() int32 { @@ -605,7 +547,7 @@ type AvailableKeychainsResponse struct { func (x *AvailableKeychainsResponse) Reset() { *x = AvailableKeychainsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[6] + mi := &file_bridge_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -618,7 +560,7 @@ func (x *AvailableKeychainsResponse) String() string { func (*AvailableKeychainsResponse) ProtoMessage() {} func (x *AvailableKeychainsResponse) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[6] + mi := &file_bridge_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -631,7 +573,7 @@ func (x *AvailableKeychainsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AvailableKeychainsResponse.ProtoReflect.Descriptor instead. func (*AvailableKeychainsResponse) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{6} + return file_bridge_proto_rawDescGZIP(), []int{5} } func (x *AvailableKeychainsResponse) GetKeychains() []string { @@ -664,7 +606,7 @@ type User struct { func (x *User) Reset() { *x = User{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[7] + mi := &file_bridge_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -677,7 +619,7 @@ func (x *User) String() string { func (*User) ProtoMessage() {} func (x *User) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[7] + mi := &file_bridge_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -690,7 +632,7 @@ func (x *User) ProtoReflect() protoreflect.Message { // Deprecated: Use User.ProtoReflect.Descriptor instead. func (*User) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{7} + return file_bridge_proto_rawDescGZIP(), []int{6} } func (x *User) GetId() string { @@ -775,7 +717,7 @@ type UserSplitModeRequest struct { func (x *UserSplitModeRequest) Reset() { *x = UserSplitModeRequest{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[8] + mi := &file_bridge_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -788,7 +730,7 @@ func (x *UserSplitModeRequest) String() string { func (*UserSplitModeRequest) ProtoMessage() {} func (x *UserSplitModeRequest) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[8] + mi := &file_bridge_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -801,7 +743,7 @@ func (x *UserSplitModeRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UserSplitModeRequest.ProtoReflect.Descriptor instead. func (*UserSplitModeRequest) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{8} + return file_bridge_proto_rawDescGZIP(), []int{7} } func (x *UserSplitModeRequest) GetUserID() string { @@ -829,7 +771,7 @@ type UserListResponse struct { func (x *UserListResponse) Reset() { *x = UserListResponse{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[9] + mi := &file_bridge_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -842,7 +784,7 @@ func (x *UserListResponse) String() string { func (*UserListResponse) ProtoMessage() {} func (x *UserListResponse) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[9] + mi := &file_bridge_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -855,7 +797,7 @@ func (x *UserListResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UserListResponse.ProtoReflect.Descriptor instead. func (*UserListResponse) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{9} + return file_bridge_proto_rawDescGZIP(), []int{8} } func (x *UserListResponse) GetUsers() []*User { @@ -877,7 +819,7 @@ type ConfigureAppleMailRequest struct { func (x *ConfigureAppleMailRequest) Reset() { *x = ConfigureAppleMailRequest{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[10] + mi := &file_bridge_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -890,7 +832,7 @@ func (x *ConfigureAppleMailRequest) String() string { func (*ConfigureAppleMailRequest) ProtoMessage() {} func (x *ConfigureAppleMailRequest) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[10] + mi := &file_bridge_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -903,7 +845,7 @@ func (x *ConfigureAppleMailRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ConfigureAppleMailRequest.ProtoReflect.Descriptor instead. func (*ConfigureAppleMailRequest) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{10} + return file_bridge_proto_rawDescGZIP(), []int{9} } func (x *ConfigureAppleMailRequest) GetUserID() string { @@ -943,7 +885,7 @@ type StreamEvent struct { func (x *StreamEvent) Reset() { *x = StreamEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[11] + mi := &file_bridge_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -956,7 +898,7 @@ func (x *StreamEvent) String() string { func (*StreamEvent) ProtoMessage() {} func (x *StreamEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[11] + mi := &file_bridge_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -969,7 +911,7 @@ func (x *StreamEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use StreamEvent.ProtoReflect.Descriptor instead. func (*StreamEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{11} + return file_bridge_proto_rawDescGZIP(), []int{10} } func (m *StreamEvent) GetEvent() isStreamEvent_Event { @@ -1097,7 +1039,7 @@ type AppEvent struct { // Types that are assignable to Event: // *AppEvent_InternetStatus - // *AppEvent_AutostartFinished + // *AppEvent_ToggleAutostartFinished // *AppEvent_ResetFinished // *AppEvent_ReportBugFinished // *AppEvent_ReportBugSuccess @@ -1109,7 +1051,7 @@ type AppEvent struct { func (x *AppEvent) Reset() { *x = AppEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[12] + mi := &file_bridge_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1122,7 +1064,7 @@ func (x *AppEvent) String() string { func (*AppEvent) ProtoMessage() {} func (x *AppEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[12] + mi := &file_bridge_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1135,7 +1077,7 @@ func (x *AppEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use AppEvent.ProtoReflect.Descriptor instead. func (*AppEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{12} + return file_bridge_proto_rawDescGZIP(), []int{11} } func (m *AppEvent) GetEvent() isAppEvent_Event { @@ -1152,9 +1094,9 @@ func (x *AppEvent) GetInternetStatus() *InternetStatusEvent { return nil } -func (x *AppEvent) GetAutostartFinished() *AutostartFinishedEvent { - if x, ok := x.GetEvent().(*AppEvent_AutostartFinished); ok { - return x.AutostartFinished +func (x *AppEvent) GetToggleAutostartFinished() *ToggleAutostartFinishedEvent { + if x, ok := x.GetEvent().(*AppEvent_ToggleAutostartFinished); ok { + return x.ToggleAutostartFinished } return nil } @@ -1202,8 +1144,8 @@ type AppEvent_InternetStatus struct { InternetStatus *InternetStatusEvent `protobuf:"bytes,1,opt,name=internetStatus,proto3,oneof"` } -type AppEvent_AutostartFinished struct { - AutostartFinished *AutostartFinishedEvent `protobuf:"bytes,2,opt,name=autostartFinished,proto3,oneof"` +type AppEvent_ToggleAutostartFinished struct { + ToggleAutostartFinished *ToggleAutostartFinishedEvent `protobuf:"bytes,2,opt,name=toggleAutostartFinished,proto3,oneof"` } type AppEvent_ResetFinished struct { @@ -1228,7 +1170,7 @@ type AppEvent_ShowMainWindow struct { func (*AppEvent_InternetStatus) isAppEvent_Event() {} -func (*AppEvent_AutostartFinished) isAppEvent_Event() {} +func (*AppEvent_ToggleAutostartFinished) isAppEvent_Event() {} func (*AppEvent_ResetFinished) isAppEvent_Event() {} @@ -1251,7 +1193,7 @@ type InternetStatusEvent struct { func (x *InternetStatusEvent) Reset() { *x = InternetStatusEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[13] + mi := &file_bridge_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1264,7 +1206,7 @@ func (x *InternetStatusEvent) String() string { func (*InternetStatusEvent) ProtoMessage() {} func (x *InternetStatusEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[13] + mi := &file_bridge_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1277,7 +1219,7 @@ func (x *InternetStatusEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use InternetStatusEvent.ProtoReflect.Descriptor instead. func (*InternetStatusEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{13} + return file_bridge_proto_rawDescGZIP(), []int{12} } func (x *InternetStatusEvent) GetConnected() bool { @@ -1287,29 +1229,29 @@ func (x *InternetStatusEvent) GetConnected() bool { return false } -type AutostartFinishedEvent struct { +type ToggleAutostartFinishedEvent struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields } -func (x *AutostartFinishedEvent) Reset() { - *x = AutostartFinishedEvent{} +func (x *ToggleAutostartFinishedEvent) Reset() { + *x = ToggleAutostartFinishedEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[14] + mi := &file_bridge_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *AutostartFinishedEvent) String() string { +func (x *ToggleAutostartFinishedEvent) String() string { return protoimpl.X.MessageStringOf(x) } -func (*AutostartFinishedEvent) ProtoMessage() {} +func (*ToggleAutostartFinishedEvent) ProtoMessage() {} -func (x *AutostartFinishedEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[14] +func (x *ToggleAutostartFinishedEvent) ProtoReflect() protoreflect.Message { + mi := &file_bridge_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1320,9 +1262,9 @@ func (x *AutostartFinishedEvent) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use AutostartFinishedEvent.ProtoReflect.Descriptor instead. -func (*AutostartFinishedEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{14} +// Deprecated: Use ToggleAutostartFinishedEvent.ProtoReflect.Descriptor instead. +func (*ToggleAutostartFinishedEvent) Descriptor() ([]byte, []int) { + return file_bridge_proto_rawDescGZIP(), []int{13} } type ResetFinishedEvent struct { @@ -1334,7 +1276,7 @@ type ResetFinishedEvent struct { func (x *ResetFinishedEvent) Reset() { *x = ResetFinishedEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[15] + mi := &file_bridge_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1347,7 +1289,7 @@ func (x *ResetFinishedEvent) String() string { func (*ResetFinishedEvent) ProtoMessage() {} func (x *ResetFinishedEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[15] + mi := &file_bridge_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1360,7 +1302,7 @@ func (x *ResetFinishedEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use ResetFinishedEvent.ProtoReflect.Descriptor instead. func (*ResetFinishedEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{15} + return file_bridge_proto_rawDescGZIP(), []int{14} } type ReportBugFinishedEvent struct { @@ -1372,7 +1314,7 @@ type ReportBugFinishedEvent struct { func (x *ReportBugFinishedEvent) Reset() { *x = ReportBugFinishedEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[16] + mi := &file_bridge_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1385,7 +1327,7 @@ func (x *ReportBugFinishedEvent) String() string { func (*ReportBugFinishedEvent) ProtoMessage() {} func (x *ReportBugFinishedEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[16] + mi := &file_bridge_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1398,7 +1340,7 @@ func (x *ReportBugFinishedEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportBugFinishedEvent.ProtoReflect.Descriptor instead. func (*ReportBugFinishedEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{16} + return file_bridge_proto_rawDescGZIP(), []int{15} } type ReportBugSuccessEvent struct { @@ -1410,7 +1352,7 @@ type ReportBugSuccessEvent struct { func (x *ReportBugSuccessEvent) Reset() { *x = ReportBugSuccessEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[17] + mi := &file_bridge_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1423,7 +1365,7 @@ func (x *ReportBugSuccessEvent) String() string { func (*ReportBugSuccessEvent) ProtoMessage() {} func (x *ReportBugSuccessEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[17] + mi := &file_bridge_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1436,7 +1378,7 @@ func (x *ReportBugSuccessEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportBugSuccessEvent.ProtoReflect.Descriptor instead. func (*ReportBugSuccessEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{17} + return file_bridge_proto_rawDescGZIP(), []int{16} } type ReportBugErrorEvent struct { @@ -1448,7 +1390,7 @@ type ReportBugErrorEvent struct { func (x *ReportBugErrorEvent) Reset() { *x = ReportBugErrorEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[18] + mi := &file_bridge_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1461,7 +1403,7 @@ func (x *ReportBugErrorEvent) String() string { func (*ReportBugErrorEvent) ProtoMessage() {} func (x *ReportBugErrorEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[18] + mi := &file_bridge_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1474,7 +1416,7 @@ func (x *ReportBugErrorEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportBugErrorEvent.ProtoReflect.Descriptor instead. func (*ReportBugErrorEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{18} + return file_bridge_proto_rawDescGZIP(), []int{17} } type ShowMainWindowEvent struct { @@ -1486,7 +1428,7 @@ type ShowMainWindowEvent struct { func (x *ShowMainWindowEvent) Reset() { *x = ShowMainWindowEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[19] + mi := &file_bridge_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1499,7 +1441,7 @@ func (x *ShowMainWindowEvent) String() string { func (*ShowMainWindowEvent) ProtoMessage() {} func (x *ShowMainWindowEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[19] + mi := &file_bridge_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1512,7 +1454,7 @@ func (x *ShowMainWindowEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use ShowMainWindowEvent.ProtoReflect.Descriptor instead. func (*ShowMainWindowEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{19} + return file_bridge_proto_rawDescGZIP(), []int{18} } //********************************************************** @@ -1528,13 +1470,14 @@ type LoginEvent struct { // *LoginEvent_TfaRequested // *LoginEvent_TwoPasswordRequested // *LoginEvent_Finished + // *LoginEvent_AlreadyLoggedIn Event isLoginEvent_Event `protobuf_oneof:"event"` } func (x *LoginEvent) Reset() { *x = LoginEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[20] + mi := &file_bridge_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1547,7 +1490,7 @@ func (x *LoginEvent) String() string { func (*LoginEvent) ProtoMessage() {} func (x *LoginEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[20] + mi := &file_bridge_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1560,7 +1503,7 @@ func (x *LoginEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use LoginEvent.ProtoReflect.Descriptor instead. func (*LoginEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{20} + return file_bridge_proto_rawDescGZIP(), []int{19} } func (m *LoginEvent) GetEvent() isLoginEvent_Event { @@ -1598,6 +1541,13 @@ func (x *LoginEvent) GetFinished() *LoginFinishedEvent { return nil } +func (x *LoginEvent) GetAlreadyLoggedIn() *LoginFinishedEvent { + if x, ok := x.GetEvent().(*LoginEvent_AlreadyLoggedIn); ok { + return x.AlreadyLoggedIn + } + return nil +} + type isLoginEvent_Event interface { isLoginEvent_Event() } @@ -1618,6 +1568,10 @@ type LoginEvent_Finished struct { Finished *LoginFinishedEvent `protobuf:"bytes,4,opt,name=finished,proto3,oneof"` } +type LoginEvent_AlreadyLoggedIn struct { + AlreadyLoggedIn *LoginFinishedEvent `protobuf:"bytes,5,opt,name=alreadyLoggedIn,proto3,oneof"` +} + func (*LoginEvent_Error) isLoginEvent_Event() {} func (*LoginEvent_TfaRequested) isLoginEvent_Event() {} @@ -1626,19 +1580,21 @@ func (*LoginEvent_TwoPasswordRequested) isLoginEvent_Event() {} func (*LoginEvent_Finished) isLoginEvent_Event() {} +func (*LoginEvent_AlreadyLoggedIn) isLoginEvent_Event() {} + type LoginErrorEvent struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Type LoginErrorType `protobuf:"varint,1,opt,name=type,proto3,enum=bridgerpc.LoginErrorType" json:"type,omitempty"` + Type LoginErrorType `protobuf:"varint,1,opt,name=type,proto3,enum=grpc.LoginErrorType" json:"type,omitempty"` Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` } func (x *LoginErrorEvent) Reset() { *x = LoginErrorEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[21] + mi := &file_bridge_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1651,7 +1607,7 @@ func (x *LoginErrorEvent) String() string { func (*LoginErrorEvent) ProtoMessage() {} func (x *LoginErrorEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[21] + mi := &file_bridge_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1664,7 +1620,7 @@ func (x *LoginErrorEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use LoginErrorEvent.ProtoReflect.Descriptor instead. func (*LoginErrorEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{21} + return file_bridge_proto_rawDescGZIP(), []int{20} } func (x *LoginErrorEvent) GetType() LoginErrorType { @@ -1692,7 +1648,7 @@ type LoginTfaRequestedEvent struct { func (x *LoginTfaRequestedEvent) Reset() { *x = LoginTfaRequestedEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[22] + mi := &file_bridge_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1705,7 +1661,7 @@ func (x *LoginTfaRequestedEvent) String() string { func (*LoginTfaRequestedEvent) ProtoMessage() {} func (x *LoginTfaRequestedEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[22] + mi := &file_bridge_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1718,7 +1674,7 @@ func (x *LoginTfaRequestedEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use LoginTfaRequestedEvent.ProtoReflect.Descriptor instead. func (*LoginTfaRequestedEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{22} + return file_bridge_proto_rawDescGZIP(), []int{21} } func (x *LoginTfaRequestedEvent) GetUsername() string { @@ -1737,7 +1693,7 @@ type LoginTwoPasswordsRequestedEvent struct { func (x *LoginTwoPasswordsRequestedEvent) Reset() { *x = LoginTwoPasswordsRequestedEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[23] + mi := &file_bridge_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1750,7 +1706,7 @@ func (x *LoginTwoPasswordsRequestedEvent) String() string { func (*LoginTwoPasswordsRequestedEvent) ProtoMessage() {} func (x *LoginTwoPasswordsRequestedEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[23] + mi := &file_bridge_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1763,7 +1719,7 @@ func (x *LoginTwoPasswordsRequestedEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use LoginTwoPasswordsRequestedEvent.ProtoReflect.Descriptor instead. func (*LoginTwoPasswordsRequestedEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{23} + return file_bridge_proto_rawDescGZIP(), []int{22} } type LoginFinishedEvent struct { @@ -1771,13 +1727,13 @@ type LoginFinishedEvent struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - WasAlreadyLoggedIn bool `protobuf:"varint,1,opt,name=wasAlreadyLoggedIn,proto3" json:"wasAlreadyLoggedIn,omitempty"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID,omitempty"` } func (x *LoginFinishedEvent) Reset() { *x = LoginFinishedEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[24] + mi := &file_bridge_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1790,7 +1746,7 @@ func (x *LoginFinishedEvent) String() string { func (*LoginFinishedEvent) ProtoMessage() {} func (x *LoginFinishedEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[24] + mi := &file_bridge_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1803,14 +1759,14 @@ func (x *LoginFinishedEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use LoginFinishedEvent.ProtoReflect.Descriptor instead. func (*LoginFinishedEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{24} + return file_bridge_proto_rawDescGZIP(), []int{23} } -func (x *LoginFinishedEvent) GetWasAlreadyLoggedIn() bool { +func (x *LoginFinishedEvent) GetUserID() string { if x != nil { - return x.WasAlreadyLoggedIn + return x.UserID } - return false + return "" } //********************************************************** @@ -1835,7 +1791,7 @@ type UpdateEvent struct { func (x *UpdateEvent) Reset() { *x = UpdateEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[25] + mi := &file_bridge_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1848,7 +1804,7 @@ func (x *UpdateEvent) String() string { func (*UpdateEvent) ProtoMessage() {} func (x *UpdateEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[25] + mi := &file_bridge_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1861,7 +1817,7 @@ func (x *UpdateEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateEvent.ProtoReflect.Descriptor instead. func (*UpdateEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{25} + return file_bridge_proto_rawDescGZIP(), []int{24} } func (m *UpdateEvent) GetEvent() isUpdateEvent_Event { @@ -1971,13 +1927,13 @@ type UpdateErrorEvent struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Type UpdateErrorType `protobuf:"varint,1,opt,name=type,proto3,enum=bridgerpc.UpdateErrorType" json:"type,omitempty"` + Type UpdateErrorType `protobuf:"varint,1,opt,name=type,proto3,enum=grpc.UpdateErrorType" json:"type,omitempty"` } func (x *UpdateErrorEvent) Reset() { *x = UpdateErrorEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[26] + mi := &file_bridge_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1990,7 +1946,7 @@ func (x *UpdateErrorEvent) String() string { func (*UpdateErrorEvent) ProtoMessage() {} func (x *UpdateErrorEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[26] + mi := &file_bridge_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2003,7 +1959,7 @@ func (x *UpdateErrorEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateErrorEvent.ProtoReflect.Descriptor instead. func (*UpdateErrorEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{26} + return file_bridge_proto_rawDescGZIP(), []int{25} } func (x *UpdateErrorEvent) GetType() UpdateErrorType { @@ -2024,7 +1980,7 @@ type UpdateManualReadyEvent struct { func (x *UpdateManualReadyEvent) Reset() { *x = UpdateManualReadyEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[27] + mi := &file_bridge_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2037,7 +1993,7 @@ func (x *UpdateManualReadyEvent) String() string { func (*UpdateManualReadyEvent) ProtoMessage() {} func (x *UpdateManualReadyEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[27] + mi := &file_bridge_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2050,7 +2006,7 @@ func (x *UpdateManualReadyEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateManualReadyEvent.ProtoReflect.Descriptor instead. func (*UpdateManualReadyEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{27} + return file_bridge_proto_rawDescGZIP(), []int{26} } func (x *UpdateManualReadyEvent) GetVersion() string { @@ -2069,7 +2025,7 @@ type UpdateManualRestartNeededEvent struct { func (x *UpdateManualRestartNeededEvent) Reset() { *x = UpdateManualRestartNeededEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[28] + mi := &file_bridge_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2082,7 +2038,7 @@ func (x *UpdateManualRestartNeededEvent) String() string { func (*UpdateManualRestartNeededEvent) ProtoMessage() {} func (x *UpdateManualRestartNeededEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[28] + mi := &file_bridge_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2095,7 +2051,7 @@ func (x *UpdateManualRestartNeededEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateManualRestartNeededEvent.ProtoReflect.Descriptor instead. func (*UpdateManualRestartNeededEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{28} + return file_bridge_proto_rawDescGZIP(), []int{27} } type UpdateForceEvent struct { @@ -2109,7 +2065,7 @@ type UpdateForceEvent struct { func (x *UpdateForceEvent) Reset() { *x = UpdateForceEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[29] + mi := &file_bridge_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2122,7 +2078,7 @@ func (x *UpdateForceEvent) String() string { func (*UpdateForceEvent) ProtoMessage() {} func (x *UpdateForceEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[29] + mi := &file_bridge_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2135,7 +2091,7 @@ func (x *UpdateForceEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateForceEvent.ProtoReflect.Descriptor instead. func (*UpdateForceEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{29} + return file_bridge_proto_rawDescGZIP(), []int{28} } func (x *UpdateForceEvent) GetVersion() string { @@ -2154,7 +2110,7 @@ type UpdateSilentRestartNeeded struct { func (x *UpdateSilentRestartNeeded) Reset() { *x = UpdateSilentRestartNeeded{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[30] + mi := &file_bridge_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2167,7 +2123,7 @@ func (x *UpdateSilentRestartNeeded) String() string { func (*UpdateSilentRestartNeeded) ProtoMessage() {} func (x *UpdateSilentRestartNeeded) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[30] + mi := &file_bridge_proto_msgTypes[29] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2180,7 +2136,7 @@ func (x *UpdateSilentRestartNeeded) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateSilentRestartNeeded.ProtoReflect.Descriptor instead. func (*UpdateSilentRestartNeeded) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{30} + return file_bridge_proto_rawDescGZIP(), []int{29} } type UpdateIsLatestVersion struct { @@ -2192,7 +2148,7 @@ type UpdateIsLatestVersion struct { func (x *UpdateIsLatestVersion) Reset() { *x = UpdateIsLatestVersion{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[31] + mi := &file_bridge_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2205,7 +2161,7 @@ func (x *UpdateIsLatestVersion) String() string { func (*UpdateIsLatestVersion) ProtoMessage() {} func (x *UpdateIsLatestVersion) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[31] + mi := &file_bridge_proto_msgTypes[30] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2218,7 +2174,7 @@ func (x *UpdateIsLatestVersion) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateIsLatestVersion.ProtoReflect.Descriptor instead. func (*UpdateIsLatestVersion) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{31} + return file_bridge_proto_rawDescGZIP(), []int{30} } type UpdateCheckFinished struct { @@ -2230,7 +2186,7 @@ type UpdateCheckFinished struct { func (x *UpdateCheckFinished) Reset() { *x = UpdateCheckFinished{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[32] + mi := &file_bridge_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2243,7 +2199,7 @@ func (x *UpdateCheckFinished) String() string { func (*UpdateCheckFinished) ProtoMessage() {} func (x *UpdateCheckFinished) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[32] + mi := &file_bridge_proto_msgTypes[31] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2256,7 +2212,7 @@ func (x *UpdateCheckFinished) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateCheckFinished.ProtoReflect.Descriptor instead. func (*UpdateCheckFinished) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{32} + return file_bridge_proto_rawDescGZIP(), []int{31} } //********************************************************** @@ -2271,13 +2227,15 @@ type CacheEvent struct { // *CacheEvent_Error // *CacheEvent_LocationChangedSuccess // *CacheEvent_ChangeLocalCacheFinished + // *CacheEvent_IsCacheOnDiskEnabledChanged + // *CacheEvent_DiskCachePathChanged Event isCacheEvent_Event `protobuf_oneof:"event"` } func (x *CacheEvent) Reset() { *x = CacheEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[33] + mi := &file_bridge_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2290,7 +2248,7 @@ func (x *CacheEvent) String() string { func (*CacheEvent) ProtoMessage() {} func (x *CacheEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[33] + mi := &file_bridge_proto_msgTypes[32] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2303,7 +2261,7 @@ func (x *CacheEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use CacheEvent.ProtoReflect.Descriptor instead. func (*CacheEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{33} + return file_bridge_proto_rawDescGZIP(), []int{32} } func (m *CacheEvent) GetEvent() isCacheEvent_Event { @@ -2334,6 +2292,20 @@ func (x *CacheEvent) GetChangeLocalCacheFinished() *ChangeLocalCacheFinishedEven return nil } +func (x *CacheEvent) GetIsCacheOnDiskEnabledChanged() *IsCacheOnDiskEnabledChanged { + if x, ok := x.GetEvent().(*CacheEvent_IsCacheOnDiskEnabledChanged); ok { + return x.IsCacheOnDiskEnabledChanged + } + return nil +} + +func (x *CacheEvent) GetDiskCachePathChanged() *DiskCachePathChanged { + if x, ok := x.GetEvent().(*CacheEvent_DiskCachePathChanged); ok { + return x.DiskCachePathChanged + } + return nil +} + type isCacheEvent_Event interface { isCacheEvent_Event() } @@ -2350,24 +2322,36 @@ type CacheEvent_ChangeLocalCacheFinished struct { ChangeLocalCacheFinished *ChangeLocalCacheFinishedEvent `protobuf:"bytes,3,opt,name=changeLocalCacheFinished,proto3,oneof"` } +type CacheEvent_IsCacheOnDiskEnabledChanged struct { + IsCacheOnDiskEnabledChanged *IsCacheOnDiskEnabledChanged `protobuf:"bytes,4,opt,name=isCacheOnDiskEnabledChanged,proto3,oneof"` +} + +type CacheEvent_DiskCachePathChanged struct { + DiskCachePathChanged *DiskCachePathChanged `protobuf:"bytes,5,opt,name=diskCachePathChanged,proto3,oneof"` +} + func (*CacheEvent_Error) isCacheEvent_Event() {} func (*CacheEvent_LocationChangedSuccess) isCacheEvent_Event() {} func (*CacheEvent_ChangeLocalCacheFinished) isCacheEvent_Event() {} +func (*CacheEvent_IsCacheOnDiskEnabledChanged) isCacheEvent_Event() {} + +func (*CacheEvent_DiskCachePathChanged) isCacheEvent_Event() {} + type CacheErrorEvent struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Type CacheErrorType `protobuf:"varint,1,opt,name=type,proto3,enum=bridgerpc.CacheErrorType" json:"type,omitempty"` + Type CacheErrorType `protobuf:"varint,1,opt,name=type,proto3,enum=grpc.CacheErrorType" json:"type,omitempty"` } func (x *CacheErrorEvent) Reset() { *x = CacheErrorEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[34] + mi := &file_bridge_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2380,7 +2364,7 @@ func (x *CacheErrorEvent) String() string { func (*CacheErrorEvent) ProtoMessage() {} func (x *CacheErrorEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[34] + mi := &file_bridge_proto_msgTypes[33] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2393,7 +2377,7 @@ func (x *CacheErrorEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use CacheErrorEvent.ProtoReflect.Descriptor instead. func (*CacheErrorEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{34} + return file_bridge_proto_rawDescGZIP(), []int{33} } func (x *CacheErrorEvent) GetType() CacheErrorType { @@ -2412,7 +2396,7 @@ type CacheLocationChangeSuccessEvent struct { func (x *CacheLocationChangeSuccessEvent) Reset() { *x = CacheLocationChangeSuccessEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[35] + mi := &file_bridge_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2425,7 +2409,7 @@ func (x *CacheLocationChangeSuccessEvent) String() string { func (*CacheLocationChangeSuccessEvent) ProtoMessage() {} func (x *CacheLocationChangeSuccessEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[35] + mi := &file_bridge_proto_msgTypes[34] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2438,7 +2422,7 @@ func (x *CacheLocationChangeSuccessEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use CacheLocationChangeSuccessEvent.ProtoReflect.Descriptor instead. func (*CacheLocationChangeSuccessEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{35} + return file_bridge_proto_rawDescGZIP(), []int{34} } type ChangeLocalCacheFinishedEvent struct { @@ -2450,7 +2434,7 @@ type ChangeLocalCacheFinishedEvent struct { func (x *ChangeLocalCacheFinishedEvent) Reset() { *x = ChangeLocalCacheFinishedEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[36] + mi := &file_bridge_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2463,7 +2447,7 @@ func (x *ChangeLocalCacheFinishedEvent) String() string { func (*ChangeLocalCacheFinishedEvent) ProtoMessage() {} func (x *ChangeLocalCacheFinishedEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[36] + mi := &file_bridge_proto_msgTypes[35] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2476,7 +2460,101 @@ func (x *ChangeLocalCacheFinishedEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use ChangeLocalCacheFinishedEvent.ProtoReflect.Descriptor instead. func (*ChangeLocalCacheFinishedEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{36} + return file_bridge_proto_rawDescGZIP(), []int{35} +} + +type IsCacheOnDiskEnabledChanged struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"` +} + +func (x *IsCacheOnDiskEnabledChanged) Reset() { + *x = IsCacheOnDiskEnabledChanged{} + if protoimpl.UnsafeEnabled { + mi := &file_bridge_proto_msgTypes[36] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *IsCacheOnDiskEnabledChanged) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*IsCacheOnDiskEnabledChanged) ProtoMessage() {} + +func (x *IsCacheOnDiskEnabledChanged) ProtoReflect() protoreflect.Message { + mi := &file_bridge_proto_msgTypes[36] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use IsCacheOnDiskEnabledChanged.ProtoReflect.Descriptor instead. +func (*IsCacheOnDiskEnabledChanged) Descriptor() ([]byte, []int) { + return file_bridge_proto_rawDescGZIP(), []int{36} +} + +func (x *IsCacheOnDiskEnabledChanged) GetEnabled() bool { + if x != nil { + return x.Enabled + } + return false +} + +type DiskCachePathChanged struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` +} + +func (x *DiskCachePathChanged) Reset() { + *x = DiskCachePathChanged{} + if protoimpl.UnsafeEnabled { + mi := &file_bridge_proto_msgTypes[37] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DiskCachePathChanged) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DiskCachePathChanged) ProtoMessage() {} + +func (x *DiskCachePathChanged) ProtoReflect() protoreflect.Message { + mi := &file_bridge_proto_msgTypes[37] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DiskCachePathChanged.ProtoReflect.Descriptor instead. +func (*DiskCachePathChanged) Descriptor() ([]byte, []int) { + return file_bridge_proto_rawDescGZIP(), []int{37} +} + +func (x *DiskCachePathChanged) GetPath() string { + if x != nil { + return x.Path + } + return "" } //********************************************************** @@ -2497,7 +2575,7 @@ type MailSettingsEvent struct { func (x *MailSettingsEvent) Reset() { *x = MailSettingsEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[37] + mi := &file_bridge_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2510,7 +2588,7 @@ func (x *MailSettingsEvent) String() string { func (*MailSettingsEvent) ProtoMessage() {} func (x *MailSettingsEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[37] + mi := &file_bridge_proto_msgTypes[38] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2523,7 +2601,7 @@ func (x *MailSettingsEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use MailSettingsEvent.ProtoReflect.Descriptor instead. func (*MailSettingsEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{37} + return file_bridge_proto_rawDescGZIP(), []int{38} } func (m *MailSettingsEvent) GetEvent() isMailSettingsEvent_Event { @@ -2581,13 +2659,13 @@ type MailSettingsErrorEvent struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Type MailSettingsErrorType `protobuf:"varint,1,opt,name=type,proto3,enum=bridgerpc.MailSettingsErrorType" json:"type,omitempty"` + Type MailSettingsErrorType `protobuf:"varint,1,opt,name=type,proto3,enum=grpc.MailSettingsErrorType" json:"type,omitempty"` } func (x *MailSettingsErrorEvent) Reset() { *x = MailSettingsErrorEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[38] + mi := &file_bridge_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2600,7 +2678,7 @@ func (x *MailSettingsErrorEvent) String() string { func (*MailSettingsErrorEvent) ProtoMessage() {} func (x *MailSettingsErrorEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[38] + mi := &file_bridge_proto_msgTypes[39] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2613,7 +2691,7 @@ func (x *MailSettingsErrorEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use MailSettingsErrorEvent.ProtoReflect.Descriptor instead. func (*MailSettingsErrorEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{38} + return file_bridge_proto_rawDescGZIP(), []int{39} } func (x *MailSettingsErrorEvent) GetType() MailSettingsErrorType { @@ -2632,7 +2710,7 @@ type UseSslForSmtpFinishedEvent struct { func (x *UseSslForSmtpFinishedEvent) Reset() { *x = UseSslForSmtpFinishedEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[39] + mi := &file_bridge_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2645,7 +2723,7 @@ func (x *UseSslForSmtpFinishedEvent) String() string { func (*UseSslForSmtpFinishedEvent) ProtoMessage() {} func (x *UseSslForSmtpFinishedEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[39] + mi := &file_bridge_proto_msgTypes[40] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2658,7 +2736,7 @@ func (x *UseSslForSmtpFinishedEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use UseSslForSmtpFinishedEvent.ProtoReflect.Descriptor instead. func (*UseSslForSmtpFinishedEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{39} + return file_bridge_proto_rawDescGZIP(), []int{40} } type ChangePortsFinishedEvent struct { @@ -2670,7 +2748,7 @@ type ChangePortsFinishedEvent struct { func (x *ChangePortsFinishedEvent) Reset() { *x = ChangePortsFinishedEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[40] + mi := &file_bridge_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2683,7 +2761,7 @@ func (x *ChangePortsFinishedEvent) String() string { func (*ChangePortsFinishedEvent) ProtoMessage() {} func (x *ChangePortsFinishedEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[40] + mi := &file_bridge_proto_msgTypes[41] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2696,7 +2774,7 @@ func (x *ChangePortsFinishedEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use ChangePortsFinishedEvent.ProtoReflect.Descriptor instead. func (*ChangePortsFinishedEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{40} + return file_bridge_proto_rawDescGZIP(), []int{41} } //********************************************************** @@ -2717,7 +2795,7 @@ type KeychainEvent struct { func (x *KeychainEvent) Reset() { *x = KeychainEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[41] + mi := &file_bridge_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2730,7 +2808,7 @@ func (x *KeychainEvent) String() string { func (*KeychainEvent) ProtoMessage() {} func (x *KeychainEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[41] + mi := &file_bridge_proto_msgTypes[42] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2743,7 +2821,7 @@ func (x *KeychainEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use KeychainEvent.ProtoReflect.Descriptor instead. func (*KeychainEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{41} + return file_bridge_proto_rawDescGZIP(), []int{42} } func (m *KeychainEvent) GetEvent() isKeychainEvent_Event { @@ -2805,7 +2883,7 @@ type ChangeKeychainFinishedEvent struct { func (x *ChangeKeychainFinishedEvent) Reset() { *x = ChangeKeychainFinishedEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[42] + mi := &file_bridge_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2818,7 +2896,7 @@ func (x *ChangeKeychainFinishedEvent) String() string { func (*ChangeKeychainFinishedEvent) ProtoMessage() {} func (x *ChangeKeychainFinishedEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[42] + mi := &file_bridge_proto_msgTypes[43] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2831,7 +2909,7 @@ func (x *ChangeKeychainFinishedEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use ChangeKeychainFinishedEvent.ProtoReflect.Descriptor instead. func (*ChangeKeychainFinishedEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{42} + return file_bridge_proto_rawDescGZIP(), []int{43} } type HasNoKeychainEvent struct { @@ -2843,7 +2921,7 @@ type HasNoKeychainEvent struct { func (x *HasNoKeychainEvent) Reset() { *x = HasNoKeychainEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[43] + mi := &file_bridge_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2856,7 +2934,7 @@ func (x *HasNoKeychainEvent) String() string { func (*HasNoKeychainEvent) ProtoMessage() {} func (x *HasNoKeychainEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[43] + mi := &file_bridge_proto_msgTypes[44] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2869,7 +2947,7 @@ func (x *HasNoKeychainEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use HasNoKeychainEvent.ProtoReflect.Descriptor instead. func (*HasNoKeychainEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{43} + return file_bridge_proto_rawDescGZIP(), []int{44} } type RebuildKeychainEvent struct { @@ -2881,7 +2959,7 @@ type RebuildKeychainEvent struct { func (x *RebuildKeychainEvent) Reset() { *x = RebuildKeychainEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[44] + mi := &file_bridge_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2894,7 +2972,7 @@ func (x *RebuildKeychainEvent) String() string { func (*RebuildKeychainEvent) ProtoMessage() {} func (x *RebuildKeychainEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[44] + mi := &file_bridge_proto_msgTypes[45] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2907,7 +2985,7 @@ func (x *RebuildKeychainEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use RebuildKeychainEvent.ProtoReflect.Descriptor instead. func (*RebuildKeychainEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{44} + return file_bridge_proto_rawDescGZIP(), []int{45} } //********************************************************** @@ -2929,7 +3007,7 @@ type MailEvent struct { func (x *MailEvent) Reset() { *x = MailEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[45] + mi := &file_bridge_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2942,7 +3020,7 @@ func (x *MailEvent) String() string { func (*MailEvent) ProtoMessage() {} func (x *MailEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[45] + mi := &file_bridge_proto_msgTypes[46] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2955,7 +3033,7 @@ func (x *MailEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use MailEvent.ProtoReflect.Descriptor instead. func (*MailEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{45} + return file_bridge_proto_rawDescGZIP(), []int{46} } func (m *MailEvent) GetEvent() isMailEvent_Event { @@ -3032,7 +3110,7 @@ type NoActiveKeyForRecipientEvent struct { func (x *NoActiveKeyForRecipientEvent) Reset() { *x = NoActiveKeyForRecipientEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[46] + mi := &file_bridge_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3045,7 +3123,7 @@ func (x *NoActiveKeyForRecipientEvent) String() string { func (*NoActiveKeyForRecipientEvent) ProtoMessage() {} func (x *NoActiveKeyForRecipientEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[46] + mi := &file_bridge_proto_msgTypes[47] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3058,7 +3136,7 @@ func (x *NoActiveKeyForRecipientEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use NoActiveKeyForRecipientEvent.ProtoReflect.Descriptor instead. func (*NoActiveKeyForRecipientEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{46} + return file_bridge_proto_rawDescGZIP(), []int{47} } func (x *NoActiveKeyForRecipientEvent) GetEmail() string { @@ -3073,13 +3151,13 @@ type AddressChangedEvent struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` // TODO: user event ? + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` } func (x *AddressChangedEvent) Reset() { *x = AddressChangedEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[47] + mi := &file_bridge_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3092,7 +3170,7 @@ func (x *AddressChangedEvent) String() string { func (*AddressChangedEvent) ProtoMessage() {} func (x *AddressChangedEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[47] + mi := &file_bridge_proto_msgTypes[48] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3105,7 +3183,7 @@ func (x *AddressChangedEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use AddressChangedEvent.ProtoReflect.Descriptor instead. func (*AddressChangedEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{47} + return file_bridge_proto_rawDescGZIP(), []int{48} } func (x *AddressChangedEvent) GetAddress() string { @@ -3120,13 +3198,13 @@ type AddressChangedLogoutEvent struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` // TODO: user event ? + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` } func (x *AddressChangedLogoutEvent) Reset() { *x = AddressChangedLogoutEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[48] + mi := &file_bridge_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3139,7 +3217,7 @@ func (x *AddressChangedLogoutEvent) String() string { func (*AddressChangedLogoutEvent) ProtoMessage() {} func (x *AddressChangedLogoutEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[48] + mi := &file_bridge_proto_msgTypes[49] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3152,7 +3230,7 @@ func (x *AddressChangedLogoutEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use AddressChangedLogoutEvent.ProtoReflect.Descriptor instead. func (*AddressChangedLogoutEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{48} + return file_bridge_proto_rawDescGZIP(), []int{49} } func (x *AddressChangedLogoutEvent) GetAddress() string { @@ -3171,7 +3249,7 @@ type ApiCertIssueEvent struct { func (x *ApiCertIssueEvent) Reset() { *x = ApiCertIssueEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[49] + mi := &file_bridge_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3184,7 +3262,7 @@ func (x *ApiCertIssueEvent) String() string { func (*ApiCertIssueEvent) ProtoMessage() {} func (x *ApiCertIssueEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[49] + mi := &file_bridge_proto_msgTypes[50] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3197,7 +3275,7 @@ func (x *ApiCertIssueEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use ApiCertIssueEvent.ProtoReflect.Descriptor instead. func (*ApiCertIssueEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{49} + return file_bridge_proto_rawDescGZIP(), []int{50} } type UserEvent struct { @@ -3215,7 +3293,7 @@ type UserEvent struct { func (x *UserEvent) Reset() { *x = UserEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[50] + mi := &file_bridge_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3228,7 +3306,7 @@ func (x *UserEvent) String() string { func (*UserEvent) ProtoMessage() {} func (x *UserEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[50] + mi := &file_bridge_proto_msgTypes[51] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3241,7 +3319,7 @@ func (x *UserEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use UserEvent.ProtoReflect.Descriptor instead. func (*UserEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{50} + return file_bridge_proto_rawDescGZIP(), []int{51} } func (m *UserEvent) GetEvent() isUserEvent_Event { @@ -3305,7 +3383,7 @@ type ToggleSplitModeFinishedEvent struct { func (x *ToggleSplitModeFinishedEvent) Reset() { *x = ToggleSplitModeFinishedEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[51] + mi := &file_bridge_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3318,7 +3396,7 @@ func (x *ToggleSplitModeFinishedEvent) String() string { func (*ToggleSplitModeFinishedEvent) ProtoMessage() {} func (x *ToggleSplitModeFinishedEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[51] + mi := &file_bridge_proto_msgTypes[52] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3331,7 +3409,7 @@ func (x *ToggleSplitModeFinishedEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use ToggleSplitModeFinishedEvent.ProtoReflect.Descriptor instead. func (*ToggleSplitModeFinishedEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{51} + return file_bridge_proto_rawDescGZIP(), []int{52} } func (x *ToggleSplitModeFinishedEvent) GetUserID() string { @@ -3346,13 +3424,13 @@ type UserDisconnectedEvent struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` // TODO: isn't it userID ? + Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` } func (x *UserDisconnectedEvent) Reset() { *x = UserDisconnectedEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[52] + mi := &file_bridge_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3365,7 +3443,7 @@ func (x *UserDisconnectedEvent) String() string { func (*UserDisconnectedEvent) ProtoMessage() {} func (x *UserDisconnectedEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[52] + mi := &file_bridge_proto_msgTypes[53] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3378,7 +3456,7 @@ func (x *UserDisconnectedEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use UserDisconnectedEvent.ProtoReflect.Descriptor instead. func (*UserDisconnectedEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{52} + return file_bridge_proto_rawDescGZIP(), []int{53} } func (x *UserDisconnectedEvent) GetUsername() string { @@ -3393,13 +3471,13 @@ type UserChangedEvent struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - User *User `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` + UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID,omitempty"` } func (x *UserChangedEvent) Reset() { *x = UserChangedEvent{} if protoimpl.UnsafeEnabled { - mi := &file_bridge_rpc_proto_msgTypes[53] + mi := &file_bridge_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3412,7 +3490,7 @@ func (x *UserChangedEvent) String() string { func (*UserChangedEvent) ProtoMessage() {} func (x *UserChangedEvent) ProtoReflect() protoreflect.Message { - mi := &file_bridge_rpc_proto_msgTypes[53] + mi := &file_bridge_proto_msgTypes[54] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3425,663 +3503,609 @@ func (x *UserChangedEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use UserChangedEvent.ProtoReflect.Descriptor instead. func (*UserChangedEvent) Descriptor() ([]byte, []int) { - return file_bridge_rpc_proto_rawDescGZIP(), []int{53} + return file_bridge_proto_rawDescGZIP(), []int{54} } -func (x *UserChangedEvent) GetUser() *User { +func (x *UserChangedEvent) GetUserID() string { if x != nil { - return x.User + return x.UserID } - return nil + return "" } -var File_bridge_rpc_proto protoreflect.FileDescriptor +var File_bridge_proto protoreflect.FileDescriptor -var file_bridge_rpc_proto_rawDesc = []byte{ - 0x0a, 0x10, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x5f, 0x72, 0x70, 0x63, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x12, 0x09, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x1a, 0x1b, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, - 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, - 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x2b, 0x0a, 0x0d, 0x50, 0x6f, - 0x69, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0c, 0x0a, 0x01, 0x78, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x01, 0x78, 0x12, 0x0c, 0x0a, 0x01, 0x79, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x01, 0x79, 0x22, 0x92, 0x01, 0x0a, 0x10, 0x52, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x42, 0x75, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, - 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, - 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x6d, 0x61, 0x69, - 0x6c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, - 0x6d, 0x61, 0x69, 0x6c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x6e, - 0x63, 0x6c, 0x75, 0x64, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0b, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x22, 0x46, 0x0a, 0x0c, - 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, - 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, - 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, - 0x77, 0x6f, 0x72, 0x64, 0x22, 0x2f, 0x0a, 0x11, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x41, 0x62, 0x6f, - 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, - 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, - 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x69, 0x0a, 0x17, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4c, - 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x61, 0x63, 0x68, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x28, 0x0a, 0x0f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x69, 0x73, 0x6b, 0x43, 0x61, - 0x63, 0x68, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x65, 0x6e, 0x61, 0x62, 0x6c, - 0x65, 0x44, 0x69, 0x73, 0x6b, 0x43, 0x61, 0x63, 0x68, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x64, 0x69, - 0x73, 0x6b, 0x43, 0x61, 0x63, 0x68, 0x65, 0x50, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0d, 0x64, 0x69, 0x73, 0x6b, 0x43, 0x61, 0x63, 0x68, 0x65, 0x50, 0x61, 0x74, 0x68, - 0x22, 0x4c, 0x0a, 0x12, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6d, 0x61, 0x70, 0x50, 0x6f, - 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x69, 0x6d, 0x61, 0x70, 0x50, 0x6f, - 0x72, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x6d, 0x74, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x73, 0x6d, 0x74, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x22, 0x3a, - 0x0a, 0x1a, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, - 0x6b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x09, 0x6b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x22, 0xac, 0x02, 0x0a, 0x04, 0x55, - 0x73, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x02, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, - 0x1e, 0x0a, 0x0a, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x54, 0x65, 0x78, 0x74, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x54, 0x65, 0x78, 0x74, 0x12, - 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x67, 0x67, 0x65, 0x64, 0x49, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x08, 0x6c, 0x6f, 0x67, 0x67, 0x65, 0x64, 0x49, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x73, - 0x70, 0x6c, 0x69, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, - 0x73, 0x70, 0x6c, 0x69, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x65, 0x74, - 0x75, 0x70, 0x47, 0x75, 0x69, 0x64, 0x65, 0x53, 0x65, 0x65, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0e, 0x73, 0x65, 0x74, 0x75, 0x70, 0x47, 0x75, 0x69, 0x64, 0x65, 0x53, 0x65, 0x65, - 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x18, 0x07, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75, 0x73, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, - 0x1e, 0x0a, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, - 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x61, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, - 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x22, 0x46, 0x0a, 0x14, 0x55, 0x73, 0x65, - 0x72, 0x53, 0x70, 0x6c, 0x69, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, - 0x69, 0x76, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, - 0x65, 0x22, 0x39, 0x0a, 0x10, 0x55, 0x73, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, - 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x22, 0x4d, 0x0a, 0x19, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x4d, 0x61, - 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, - 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, - 0x44, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0xa3, 0x03, 0x0a, 0x0b, - 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x27, 0x0a, 0x03, 0x61, - 0x70, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, - 0x65, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x70, 0x70, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, - 0x03, 0x61, 0x70, 0x70, 0x12, 0x2d, 0x0a, 0x05, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, - 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x05, 0x6c, 0x6f, - 0x67, 0x69, 0x6e, 0x12, 0x30, 0x0a, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x06, 0x75, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x2d, 0x0a, 0x05, 0x63, 0x61, 0x63, 0x68, 0x65, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, - 0x2e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x05, 0x63, - 0x61, 0x63, 0x68, 0x65, 0x12, 0x42, 0x0a, 0x0c, 0x6d, 0x61, 0x69, 0x6c, 0x53, 0x65, 0x74, 0x74, - 0x69, 0x6e, 0x67, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x62, 0x72, 0x69, - 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x61, 0x69, 0x6c, 0x53, 0x65, 0x74, 0x74, 0x69, - 0x6e, 0x67, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0c, 0x6d, 0x61, 0x69, 0x6c, - 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x36, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x63, - 0x68, 0x61, 0x69, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x62, 0x72, 0x69, - 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x12, 0x2a, 0x0a, 0x04, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, - 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x61, 0x69, 0x6c, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x04, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x2a, 0x0a, 0x04, - 0x75, 0x73, 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x62, 0x72, 0x69, - 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x48, 0x00, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, - 0x74, 0x22, 0xae, 0x04, 0x0a, 0x08, 0x41, 0x70, 0x70, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x48, - 0x0a, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, - 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, - 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x51, 0x0a, 0x11, 0x61, 0x75, 0x74, 0x6f, - 0x73, 0x74, 0x61, 0x72, 0x74, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, - 0x41, 0x75, 0x74, 0x6f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, - 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x11, 0x61, 0x75, 0x74, 0x6f, 0x73, 0x74, - 0x61, 0x72, 0x74, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x12, 0x45, 0x0a, 0x0d, 0x72, - 0x65, 0x73, 0x65, 0x74, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x52, +var file_bridge_proto_rawDesc = []byte{ + 0x0a, 0x0c, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04, + 0x67, 0x72, 0x70, 0x63, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x22, 0x92, 0x01, 0x0a, 0x10, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x75, 0x67, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x43, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x43, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x4c, + 0x6f, 0x67, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x6e, 0x63, 0x6c, 0x75, + 0x64, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x22, 0x46, 0x0a, 0x0c, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x2f, + 0x0a, 0x11, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, + 0x69, 0x0a, 0x17, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x61, + 0x63, 0x68, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x65, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x44, 0x69, 0x73, 0x6b, 0x43, 0x61, 0x63, 0x68, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x69, 0x73, 0x6b, 0x43, + 0x61, 0x63, 0x68, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x64, 0x69, 0x73, 0x6b, 0x43, 0x61, 0x63, 0x68, + 0x65, 0x50, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x69, 0x73, + 0x6b, 0x43, 0x61, 0x63, 0x68, 0x65, 0x50, 0x61, 0x74, 0x68, 0x22, 0x4c, 0x0a, 0x12, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6d, 0x61, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x08, 0x69, 0x6d, 0x61, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1a, 0x0a, 0x08, + 0x73, 0x6d, 0x74, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, + 0x73, 0x6d, 0x74, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x22, 0x3a, 0x0a, 0x1a, 0x41, 0x76, 0x61, 0x69, + 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x63, 0x68, 0x61, + 0x69, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x6b, 0x65, 0x79, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x73, 0x22, 0xac, 0x02, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1a, 0x0a, + 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x76, 0x61, + 0x74, 0x61, 0x72, 0x54, 0x65, 0x78, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, + 0x76, 0x61, 0x74, 0x61, 0x72, 0x54, 0x65, 0x78, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x67, + 0x67, 0x65, 0x64, 0x49, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6c, 0x6f, 0x67, + 0x67, 0x65, 0x64, 0x49, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x4d, 0x6f, + 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x4d, + 0x6f, 0x64, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x65, 0x74, 0x75, 0x70, 0x47, 0x75, 0x69, 0x64, + 0x65, 0x53, 0x65, 0x65, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x73, 0x65, 0x74, + 0x75, 0x70, 0x47, 0x75, 0x69, 0x64, 0x65, 0x53, 0x65, 0x65, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x75, + 0x73, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, + 0x75, 0x73, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x6f, 0x74, + 0x61, 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x74, + 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, + 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, + 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x65, 0x73, 0x22, 0x46, 0x0a, 0x14, 0x55, 0x73, 0x65, 0x72, 0x53, 0x70, 0x6c, 0x69, 0x74, + 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x75, + 0x73, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, + 0x72, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x22, 0x34, 0x0a, 0x10, 0x55, + 0x73, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x20, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, + 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x05, 0x75, 0x73, 0x65, 0x72, + 0x73, 0x22, 0x4d, 0x0a, 0x19, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x41, 0x70, + 0x70, 0x6c, 0x65, 0x4d, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, + 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x75, 0x73, 0x65, 0x72, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x22, 0xfb, 0x02, 0x0a, 0x0b, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x12, 0x22, 0x0a, 0x03, 0x61, 0x70, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, + 0x67, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x70, 0x70, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, + 0x03, 0x61, 0x70, 0x70, 0x12, 0x28, 0x0a, 0x05, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x05, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x2b, + 0x0a, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x48, 0x00, 0x52, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x28, 0x0a, 0x05, 0x63, + 0x61, 0x63, 0x68, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x67, 0x72, 0x70, + 0x63, 0x2e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x05, + 0x63, 0x61, 0x63, 0x68, 0x65, 0x12, 0x3d, 0x0a, 0x0c, 0x6d, 0x61, 0x69, 0x6c, 0x53, 0x65, 0x74, + 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x72, + 0x70, 0x63, 0x2e, 0x4d, 0x61, 0x69, 0x6c, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0c, 0x6d, 0x61, 0x69, 0x6c, 0x53, 0x65, 0x74, 0x74, + 0x69, 0x6e, 0x67, 0x73, 0x12, 0x31, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x4b, 0x65, + 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x08, 0x6b, + 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x25, 0x0a, 0x04, 0x6d, 0x61, 0x69, 0x6c, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x61, 0x69, + 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x04, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x25, + 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x67, + 0x72, 0x70, 0x63, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, + 0x04, 0x75, 0x73, 0x65, 0x72, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x9d, + 0x04, 0x0a, 0x08, 0x41, 0x70, 0x70, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x43, 0x0a, 0x0e, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, + 0x6e, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, + 0x52, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x5e, 0x0a, 0x17, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x41, 0x75, 0x74, 0x6f, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x22, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x41, + 0x75, 0x74, 0x6f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x17, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x41, + 0x75, 0x74, 0x6f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, + 0x12, 0x40, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x65, 0x74, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0d, 0x72, 0x65, 0x73, 0x65, 0x74, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, - 0x65, 0x64, 0x12, 0x51, 0x0a, 0x11, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x75, 0x67, 0x46, - 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, - 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x42, 0x75, 0x67, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x48, 0x00, 0x52, 0x11, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x75, 0x67, 0x46, 0x69, 0x6e, - 0x69, 0x73, 0x68, 0x65, 0x64, 0x12, 0x4e, 0x0a, 0x10, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x42, - 0x75, 0x67, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x20, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x42, 0x75, 0x67, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x48, 0x00, 0x52, 0x10, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x75, 0x67, 0x53, 0x75, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x48, 0x0a, 0x0e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x42, - 0x75, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, - 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x42, 0x75, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, - 0x0e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x75, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, - 0x48, 0x0a, 0x0e, 0x73, 0x68, 0x6f, 0x77, 0x4d, 0x61, 0x69, 0x6e, 0x57, 0x69, 0x6e, 0x64, 0x6f, - 0x77, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, - 0x72, 0x70, 0x63, 0x2e, 0x53, 0x68, 0x6f, 0x77, 0x4d, 0x61, 0x69, 0x6e, 0x57, 0x69, 0x6e, 0x64, - 0x6f, 0x77, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0e, 0x73, 0x68, 0x6f, 0x77, 0x4d, - 0x61, 0x69, 0x6e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, - 0x6e, 0x74, 0x22, 0x33, 0x0a, 0x13, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, - 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x63, 0x6f, - 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x22, 0x18, 0x0a, 0x16, 0x41, 0x75, 0x74, 0x6f, 0x73, - 0x74, 0x61, 0x72, 0x74, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x22, 0x14, 0x0a, 0x12, 0x52, 0x65, 0x73, 0x65, 0x74, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, - 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x18, 0x0a, 0x16, 0x52, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x42, 0x75, 0x67, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x22, 0x17, 0x0a, 0x15, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x75, 0x67, 0x53, 0x75, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x15, 0x0a, 0x13, 0x52, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x42, 0x75, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x22, 0x15, 0x0a, 0x13, 0x53, 0x68, 0x6f, 0x77, 0x4d, 0x61, 0x69, 0x6e, 0x57, 0x69, 0x6e, - 0x64, 0x6f, 0x77, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0xb1, 0x02, 0x0a, 0x0a, 0x4c, 0x6f, 0x67, - 0x69, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x32, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, - 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x48, 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x47, 0x0a, 0x0c, 0x74, - 0x66, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x21, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, - 0x67, 0x69, 0x6e, 0x54, 0x66, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0c, 0x74, 0x66, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x65, 0x64, 0x12, 0x60, 0x0a, 0x14, 0x74, 0x77, 0x6f, 0x50, 0x61, 0x73, 0x73, 0x77, - 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x4c, - 0x6f, 0x67, 0x69, 0x6e, 0x54, 0x77, 0x6f, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, - 0x52, 0x14, 0x74, 0x77, 0x6f, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x12, 0x3b, 0x0a, 0x08, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, - 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, - 0x65, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, - 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x08, 0x66, 0x69, 0x6e, 0x69, 0x73, - 0x68, 0x65, 0x64, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x5a, 0x0a, 0x0f, - 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, - 0x2d, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, - 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x45, - 0x72, 0x72, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, - 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x34, 0x0a, 0x16, 0x4c, 0x6f, 0x67, 0x69, - 0x6e, 0x54, 0x66, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x21, - 0x0a, 0x1f, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x54, 0x77, 0x6f, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, + 0x65, 0x64, 0x12, 0x4c, 0x0a, 0x11, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x75, 0x67, 0x46, + 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, + 0x67, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x75, 0x67, 0x46, 0x69, + 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x11, 0x72, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x75, 0x67, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, + 0x12, 0x49, 0x0a, 0x10, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x75, 0x67, 0x53, 0x75, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x72, 0x70, + 0x63, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x75, 0x67, 0x53, 0x75, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x10, 0x72, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x42, 0x75, 0x67, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x43, 0x0a, 0x0e, 0x72, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x75, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x42, 0x75, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, + 0x52, 0x0e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x75, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, + 0x12, 0x43, 0x0a, 0x0e, 0x73, 0x68, 0x6f, 0x77, 0x4d, 0x61, 0x69, 0x6e, 0x57, 0x69, 0x6e, 0x64, + 0x6f, 0x77, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, + 0x53, 0x68, 0x6f, 0x77, 0x4d, 0x61, 0x69, 0x6e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0e, 0x73, 0x68, 0x6f, 0x77, 0x4d, 0x61, 0x69, 0x6e, 0x57, + 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x33, + 0x0a, 0x13, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x65, 0x64, 0x22, 0x1e, 0x0a, 0x1c, 0x54, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x41, 0x75, 0x74, + 0x6f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x22, 0x14, 0x0a, 0x12, 0x52, 0x65, 0x73, 0x65, 0x74, 0x46, 0x69, 0x6e, 0x69, + 0x73, 0x68, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x18, 0x0a, 0x16, 0x52, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x42, 0x75, 0x67, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x22, 0x17, 0x0a, 0x15, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x75, 0x67, + 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x15, 0x0a, 0x13, + 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x75, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x22, 0x15, 0x0a, 0x13, 0x53, 0x68, 0x6f, 0x77, 0x4d, 0x61, 0x69, 0x6e, 0x57, + 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0xe3, 0x02, 0x0a, 0x0a, 0x4c, + 0x6f, 0x67, 0x69, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2d, 0x0a, 0x05, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, + 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, + 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x42, 0x0a, 0x0c, 0x74, 0x66, 0x61, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, + 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x54, 0x66, 0x61, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0c, + 0x74, 0x66, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x12, 0x5b, 0x0a, 0x14, + 0x74, 0x77, 0x6f, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x72, 0x70, + 0x63, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x54, 0x77, 0x6f, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x22, 0x44, 0x0a, 0x12, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, - 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x12, 0x77, 0x61, 0x73, 0x41, 0x6c, - 0x72, 0x65, 0x61, 0x64, 0x79, 0x4c, 0x6f, 0x67, 0x67, 0x65, 0x64, 0x49, 0x6e, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x12, 0x77, 0x61, 0x73, 0x41, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x4c, - 0x6f, 0x67, 0x67, 0x65, 0x64, 0x49, 0x6e, 0x22, 0x96, 0x04, 0x0a, 0x0b, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x33, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, - 0x70, 0x63, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x45, 0x0a, 0x0b, - 0x6d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x52, 0x65, 0x61, 0x64, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x21, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x52, 0x65, 0x61, 0x64, 0x79, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0b, 0x6d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x52, 0x65, - 0x61, 0x64, 0x79, 0x12, 0x5d, 0x0a, 0x13, 0x6d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x52, 0x65, 0x73, - 0x74, 0x61, 0x72, 0x74, 0x4e, 0x65, 0x65, 0x64, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x29, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, - 0x4e, 0x65, 0x65, 0x64, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x13, 0x6d, - 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4e, 0x65, 0x65, 0x64, - 0x65, 0x64, 0x12, 0x33, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1b, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, - 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x58, 0x0a, 0x13, 0x73, 0x69, 0x6c, 0x65, 0x6e, - 0x74, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4e, 0x65, 0x65, 0x64, 0x65, 0x64, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, - 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x69, 0x6c, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, - 0x74, 0x61, 0x72, 0x74, 0x4e, 0x65, 0x65, 0x64, 0x65, 0x64, 0x48, 0x00, 0x52, 0x13, 0x73, 0x69, + 0x74, 0x48, 0x00, 0x52, 0x14, 0x74, 0x77, 0x6f, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x12, 0x36, 0x0a, 0x08, 0x66, 0x69, 0x6e, + 0x69, 0x73, 0x68, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x67, 0x72, + 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x08, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, + 0x64, 0x12, 0x44, 0x0a, 0x0f, 0x61, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x4c, 0x6f, 0x67, 0x67, + 0x65, 0x64, 0x49, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x67, 0x72, 0x70, + 0x63, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0f, 0x61, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x4c, + 0x6f, 0x67, 0x67, 0x65, 0x64, 0x49, 0x6e, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, + 0x22, 0x55, 0x0a, 0x0f, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x12, 0x28, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x14, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x45, 0x72, + 0x72, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, + 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x34, 0x0a, 0x16, 0x4c, 0x6f, 0x67, 0x69, 0x6e, + 0x54, 0x66, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x21, 0x0a, + 0x1f, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x54, 0x77, 0x6f, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, + 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x22, 0x2c, 0x0a, 0x12, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, + 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x44, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x44, 0x22, 0xf3, + 0x03, 0x0a, 0x0b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2e, + 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, + 0x67, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x40, + 0x0a, 0x0b, 0x6d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x52, 0x65, 0x61, 0x64, 0x79, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x52, 0x65, 0x61, 0x64, 0x79, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x48, 0x00, 0x52, 0x0b, 0x6d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x52, 0x65, 0x61, 0x64, 0x79, + 0x12, 0x58, 0x0a, 0x13, 0x6d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x4e, 0x65, 0x65, 0x64, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, + 0x67, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x6e, 0x75, 0x61, + 0x6c, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4e, 0x65, 0x65, 0x64, 0x65, 0x64, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x13, 0x6d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x52, 0x65, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x4e, 0x65, 0x65, 0x64, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x05, 0x66, 0x6f, + 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x72, 0x70, 0x63, + 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x48, 0x00, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x53, 0x0a, 0x13, 0x73, 0x69, 0x6c, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4e, 0x65, 0x65, 0x64, 0x65, - 0x64, 0x12, 0x4c, 0x0a, 0x0f, 0x69, 0x73, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x62, 0x72, 0x69, - 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x73, 0x4c, - 0x61, 0x74, 0x65, 0x73, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x0f, - 0x69, 0x73, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, - 0x46, 0x0a, 0x0d, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, - 0x70, 0x63, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x46, 0x69, - 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x48, 0x00, 0x52, 0x0d, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x46, - 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, - 0x22, 0x42, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, - 0x74, 0x79, 0x70, 0x65, 0x22, 0x32, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, - 0x6e, 0x75, 0x61, 0x6c, 0x52, 0x65, 0x61, 0x64, 0x79, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x18, - 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x20, 0x0a, 0x1e, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4e, - 0x65, 0x65, 0x64, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x2c, 0x0a, 0x10, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x18, - 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x1b, 0x0a, 0x19, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x53, 0x69, 0x6c, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4e, - 0x65, 0x65, 0x64, 0x65, 0x64, 0x22, 0x17, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, - 0x73, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x15, - 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x46, 0x69, 0x6e, - 0x69, 0x73, 0x68, 0x65, 0x64, 0x22, 0x97, 0x02, 0x0a, 0x0a, 0x43, 0x61, 0x63, 0x68, 0x65, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x12, 0x32, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, - 0x43, 0x61, 0x63, 0x68, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, - 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x64, 0x0a, 0x16, 0x6c, 0x6f, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x53, 0x75, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, - 0x65, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x16, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x66, - 0x0a, 0x18, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x61, 0x63, - 0x68, 0x65, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x28, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, + 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x69, 0x6c, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x4e, 0x65, 0x65, 0x64, 0x65, 0x64, 0x48, 0x00, 0x52, 0x13, 0x73, 0x69, 0x6c, 0x65, + 0x6e, 0x74, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4e, 0x65, 0x65, 0x64, 0x65, 0x64, 0x12, + 0x47, 0x0a, 0x0f, 0x69, 0x73, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x73, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x0f, 0x69, 0x73, 0x4c, 0x61, 0x74, 0x65, 0x73, + 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x41, 0x0a, 0x0d, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x19, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x68, 0x65, + 0x63, 0x6b, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x48, 0x00, 0x52, 0x0d, 0x63, 0x68, + 0x65, 0x63, 0x6b, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x42, 0x07, 0x0a, 0x05, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x22, 0x3d, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x72, + 0x72, 0x6f, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x29, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x22, 0x32, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x6e, + 0x75, 0x61, 0x6c, 0x52, 0x65, 0x61, 0x64, 0x79, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x18, 0x0a, + 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x20, 0x0a, 0x1e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4e, 0x65, + 0x65, 0x64, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x2c, 0x0a, 0x10, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x18, 0x0a, + 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x1b, 0x0a, 0x19, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x53, 0x69, 0x6c, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4e, 0x65, + 0x65, 0x64, 0x65, 0x64, 0x22, 0x17, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x73, + 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x15, 0x0a, + 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x46, 0x69, 0x6e, 0x69, + 0x73, 0x68, 0x65, 0x64, 0x22, 0xc1, 0x03, 0x0a, 0x0a, 0x43, 0x61, 0x63, 0x68, 0x65, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x12, 0x2d, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x12, 0x5f, 0x0a, 0x16, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x64, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x4c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x75, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x16, 0x6c, 0x6f, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x53, 0x75, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x12, 0x61, 0x0a, 0x18, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4c, 0x6f, 0x63, + 0x61, 0x6c, 0x43, 0x61, 0x63, 0x68, 0x65, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x61, 0x63, 0x68, 0x65, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x18, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x61, 0x63, 0x68, 0x65, 0x46, 0x69, - 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, - 0x40, 0x0a, 0x0f, 0x43, 0x61, 0x63, 0x68, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x12, 0x2d, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x19, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x63, - 0x68, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, - 0x65, 0x22, 0x21, 0x0a, 0x1f, 0x43, 0x61, 0x63, 0x68, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x22, 0x1f, 0x0a, 0x1d, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4c, 0x6f, - 0x63, 0x61, 0x6c, 0x43, 0x61, 0x63, 0x68, 0x65, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x8f, 0x02, 0x0a, 0x11, 0x4d, 0x61, 0x69, 0x6c, 0x53, 0x65, - 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x39, 0x0a, 0x05, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x62, 0x72, 0x69, - 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x61, 0x69, 0x6c, 0x53, 0x65, 0x74, 0x74, 0x69, - 0x6e, 0x67, 0x73, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, - 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x5d, 0x0a, 0x15, 0x75, 0x73, 0x65, 0x53, 0x73, 0x6c, - 0x46, 0x6f, 0x72, 0x53, 0x6d, 0x74, 0x70, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, - 0x63, 0x2e, 0x55, 0x73, 0x65, 0x53, 0x73, 0x6c, 0x46, 0x6f, 0x72, 0x53, 0x6d, 0x74, 0x70, 0x46, - 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x15, - 0x75, 0x73, 0x65, 0x53, 0x73, 0x6c, 0x46, 0x6f, 0x72, 0x53, 0x6d, 0x74, 0x70, 0x46, 0x69, 0x6e, - 0x69, 0x73, 0x68, 0x65, 0x64, 0x12, 0x57, 0x0a, 0x13, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, - 0x6f, 0x72, 0x74, 0x73, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x43, - 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, - 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x13, 0x63, 0x68, 0x61, 0x6e, 0x67, - 0x65, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x42, 0x07, - 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x4e, 0x0a, 0x16, 0x4d, 0x61, 0x69, 0x6c, 0x53, + 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x12, 0x65, 0x0a, 0x1b, 0x69, 0x73, 0x43, 0x61, 0x63, 0x68, + 0x65, 0x4f, 0x6e, 0x44, 0x69, 0x73, 0x6b, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x67, 0x72, + 0x70, 0x63, 0x2e, 0x49, 0x73, 0x43, 0x61, 0x63, 0x68, 0x65, 0x4f, 0x6e, 0x44, 0x69, 0x73, 0x6b, + 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x48, 0x00, + 0x52, 0x1b, 0x69, 0x73, 0x43, 0x61, 0x63, 0x68, 0x65, 0x4f, 0x6e, 0x44, 0x69, 0x73, 0x6b, 0x45, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x50, 0x0a, + 0x14, 0x64, 0x69, 0x73, 0x6b, 0x43, 0x61, 0x63, 0x68, 0x65, 0x50, 0x61, 0x74, 0x68, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x72, + 0x70, 0x63, 0x2e, 0x44, 0x69, 0x73, 0x6b, 0x43, 0x61, 0x63, 0x68, 0x65, 0x50, 0x61, 0x74, 0x68, + 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x48, 0x00, 0x52, 0x14, 0x64, 0x69, 0x73, 0x6b, 0x43, + 0x61, 0x63, 0x68, 0x65, 0x50, 0x61, 0x74, 0x68, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x42, + 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x3b, 0x0a, 0x0f, 0x43, 0x61, 0x63, 0x68, + 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x28, 0x0a, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x67, 0x72, 0x70, 0x63, + 0x2e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x52, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x21, 0x0a, 0x1f, 0x43, 0x61, 0x63, 0x68, 0x65, 0x4c, 0x6f, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x75, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x1f, 0x0a, 0x1d, 0x43, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x61, 0x63, 0x68, 0x65, 0x46, 0x69, 0x6e, 0x69, + 0x73, 0x68, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x37, 0x0a, 0x1b, 0x49, 0x73, 0x43, + 0x61, 0x63, 0x68, 0x65, 0x4f, 0x6e, 0x44, 0x69, 0x73, 0x6b, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, + 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x64, 0x22, 0x2a, 0x0a, 0x14, 0x44, 0x69, 0x73, 0x6b, 0x43, 0x61, 0x63, 0x68, 0x65, 0x50, + 0x61, 0x74, 0x68, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, + 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0x80, + 0x02, 0x0a, 0x11, 0x4d, 0x61, 0x69, 0x6c, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x12, 0x34, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x61, 0x69, 0x6c, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x12, 0x34, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x20, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x61, 0x69, 0x6c, - 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x79, 0x70, - 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x1c, 0x0a, 0x1a, 0x55, 0x73, 0x65, 0x53, 0x73, - 0x6c, 0x46, 0x6f, 0x72, 0x53, 0x6d, 0x74, 0x70, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x1a, 0x0a, 0x18, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, + 0x74, 0x48, 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x58, 0x0a, 0x15, 0x75, 0x73, + 0x65, 0x53, 0x73, 0x6c, 0x46, 0x6f, 0x72, 0x53, 0x6d, 0x74, 0x70, 0x46, 0x69, 0x6e, 0x69, 0x73, + 0x68, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x67, 0x72, 0x70, 0x63, + 0x2e, 0x55, 0x73, 0x65, 0x53, 0x73, 0x6c, 0x46, 0x6f, 0x72, 0x53, 0x6d, 0x74, 0x70, 0x46, 0x69, + 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x15, 0x75, + 0x73, 0x65, 0x53, 0x73, 0x6c, 0x46, 0x6f, 0x72, 0x53, 0x6d, 0x74, 0x70, 0x46, 0x69, 0x6e, 0x69, + 0x73, 0x68, 0x65, 0x64, 0x12, 0x52, 0x0a, 0x13, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x6f, + 0x72, 0x74, 0x73, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x22, 0x8e, 0x02, 0x0a, 0x0d, 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x12, 0x60, 0x0a, 0x16, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4b, 0x65, 0x79, - 0x63, 0x68, 0x61, 0x69, 0x6e, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, + 0x74, 0x48, 0x00, 0x52, 0x13, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x73, + 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x22, 0x49, 0x0a, 0x16, 0x4d, 0x61, 0x69, 0x6c, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, + 0x73, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2f, 0x0a, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x67, 0x72, 0x70, 0x63, + 0x2e, 0x4d, 0x61, 0x69, 0x6c, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x45, 0x72, 0x72, + 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x1c, 0x0a, 0x1a, + 0x55, 0x73, 0x65, 0x53, 0x73, 0x6c, 0x46, 0x6f, 0x72, 0x53, 0x6d, 0x74, 0x70, 0x46, 0x69, 0x6e, + 0x69, 0x73, 0x68, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x1a, 0x0a, 0x18, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, + 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0xff, 0x01, 0x0a, 0x0d, 0x4b, 0x65, 0x79, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x5b, 0x0a, 0x16, 0x63, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, + 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x16, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x46, 0x69, 0x6e, - 0x69, 0x73, 0x68, 0x65, 0x64, 0x12, 0x45, 0x0a, 0x0d, 0x68, 0x61, 0x73, 0x4e, 0x6f, 0x4b, 0x65, - 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x62, - 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x48, 0x61, 0x73, 0x4e, 0x6f, 0x4b, 0x65, - 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0d, 0x68, - 0x61, 0x73, 0x4e, 0x6f, 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x4b, 0x0a, 0x0f, - 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, - 0x63, 0x2e, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0f, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, - 0x64, 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, - 0x6e, 0x74, 0x22, 0x1d, 0x0a, 0x1b, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4b, 0x65, 0x79, 0x63, - 0x68, 0x61, 0x69, 0x6e, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x22, 0x14, 0x0a, 0x12, 0x48, 0x61, 0x73, 0x4e, 0x6f, 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x16, 0x0a, 0x14, 0x52, 0x65, 0x62, 0x75, 0x69, - 0x6c, 0x64, 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, - 0xed, 0x02, 0x0a, 0x09, 0x4d, 0x61, 0x69, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x6d, 0x0a, + 0x69, 0x73, 0x68, 0x65, 0x64, 0x12, 0x40, 0x0a, 0x0d, 0x68, 0x61, 0x73, 0x4e, 0x6f, 0x4b, 0x65, + 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x67, + 0x72, 0x70, 0x63, 0x2e, 0x48, 0x61, 0x73, 0x4e, 0x6f, 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0d, 0x68, 0x61, 0x73, 0x4e, 0x6f, 0x4b, + 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x46, 0x0a, 0x0f, 0x72, 0x65, 0x62, 0x75, 0x69, + 0x6c, 0x64, 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x4b, + 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0f, + 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x42, + 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x1d, 0x0a, 0x1b, 0x43, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, + 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x14, 0x0a, 0x12, 0x48, 0x61, 0x73, 0x4e, 0x6f, + 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x16, 0x0a, + 0x14, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0xd9, 0x02, 0x0a, 0x09, 0x4d, 0x61, 0x69, 0x6c, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x12, 0x68, 0x0a, 0x1c, 0x6e, 0x6f, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x4b, + 0x65, 0x79, 0x46, 0x6f, 0x72, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x67, 0x72, 0x70, 0x63, + 0x2e, 0x4e, 0x6f, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x6f, 0x72, 0x52, + 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1c, 0x6e, 0x6f, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x6f, 0x72, 0x52, - 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, - 0x4e, 0x6f, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x6f, 0x72, 0x52, 0x65, - 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1c, - 0x6e, 0x6f, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x6f, 0x72, 0x52, 0x65, - 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x48, 0x0a, 0x0e, - 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, - 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0e, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x43, - 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x5a, 0x0a, 0x14, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x4c, 0x6f, 0x67, 0x6f, 0x75, 0x74, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, - 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x4c, - 0x6f, 0x67, 0x6f, 0x75, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x14, 0x61, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x4c, 0x6f, 0x67, 0x6f, - 0x75, 0x74, 0x12, 0x42, 0x0a, 0x0c, 0x61, 0x70, 0x69, 0x43, 0x65, 0x72, 0x74, 0x49, 0x73, 0x73, - 0x75, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, - 0x65, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x70, 0x69, 0x43, 0x65, 0x72, 0x74, 0x49, 0x73, 0x73, 0x75, - 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0c, 0x61, 0x70, 0x69, 0x43, 0x65, 0x72, - 0x74, 0x49, 0x73, 0x73, 0x75, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, - 0x34, 0x0a, 0x1c, 0x4e, 0x6f, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x6f, - 0x72, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, - 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x2f, 0x0a, 0x13, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, - 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x35, 0x0a, 0x19, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x4c, 0x6f, 0x67, 0x6f, 0x75, 0x74, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x13, 0x0a, - 0x11, 0x41, 0x70, 0x69, 0x43, 0x65, 0x72, 0x74, 0x49, 0x73, 0x73, 0x75, 0x65, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x22, 0x8a, 0x02, 0x0a, 0x09, 0x55, 0x73, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x12, 0x63, 0x0a, 0x17, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x53, 0x70, 0x6c, 0x69, 0x74, 0x4d, - 0x6f, 0x64, 0x65, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x27, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x6f, - 0x67, 0x67, 0x6c, 0x65, 0x53, 0x70, 0x6c, 0x69, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x46, 0x69, 0x6e, - 0x69, 0x73, 0x68, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x17, 0x74, 0x6f, - 0x67, 0x67, 0x6c, 0x65, 0x53, 0x70, 0x6c, 0x69, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x46, 0x69, 0x6e, - 0x69, 0x73, 0x68, 0x65, 0x64, 0x12, 0x4e, 0x0a, 0x10, 0x75, 0x73, 0x65, 0x72, 0x44, 0x69, 0x73, - 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x20, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x73, 0x65, 0x72, - 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x48, 0x00, 0x52, 0x10, 0x75, 0x73, 0x65, 0x72, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, - 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x3f, 0x0a, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x43, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x62, 0x72, 0x69, - 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x43, 0x68, 0x61, 0x6e, 0x67, - 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x43, - 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, - 0x36, 0x0a, 0x1c, 0x54, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x53, 0x70, 0x6c, 0x69, 0x74, 0x4d, 0x6f, - 0x64, 0x65, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, - 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x44, 0x22, 0x33, 0x0a, 0x15, 0x55, 0x73, 0x65, 0x72, 0x44, - 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x37, 0x0a, 0x10, - 0x55, 0x73, 0x65, 0x72, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x12, 0x23, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, - 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, - 0x04, 0x75, 0x73, 0x65, 0x72, 0x2a, 0xa2, 0x01, 0x0a, 0x0e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x45, - 0x72, 0x72, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x55, 0x53, 0x45, 0x52, - 0x4e, 0x41, 0x4d, 0x45, 0x5f, 0x50, 0x41, 0x53, 0x53, 0x57, 0x4f, 0x52, 0x44, 0x5f, 0x45, 0x52, - 0x52, 0x4f, 0x52, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x46, 0x52, 0x45, 0x45, 0x5f, 0x55, 0x53, - 0x45, 0x52, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, - 0x4f, 0x4e, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x46, - 0x41, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x46, 0x41, - 0x5f, 0x41, 0x42, 0x4f, 0x52, 0x54, 0x10, 0x04, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x57, 0x4f, 0x5f, - 0x50, 0x41, 0x53, 0x53, 0x57, 0x4f, 0x52, 0x44, 0x53, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, - 0x05, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x57, 0x4f, 0x5f, 0x50, 0x41, 0x53, 0x53, 0x57, 0x4f, 0x52, - 0x44, 0x53, 0x5f, 0x41, 0x42, 0x4f, 0x52, 0x54, 0x10, 0x06, 0x2a, 0x5b, 0x0a, 0x0f, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, - 0x13, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x4d, 0x41, 0x4e, 0x55, 0x41, 0x4c, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, - 0x5f, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x01, 0x12, 0x17, - 0x0a, 0x13, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x49, 0x4c, 0x45, 0x4e, 0x54, 0x5f, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x2a, 0x57, 0x0a, 0x0e, 0x43, 0x61, 0x63, 0x68, 0x65, - 0x45, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x43, 0x41, 0x43, - 0x48, 0x45, 0x5f, 0x55, 0x4e, 0x41, 0x56, 0x41, 0x49, 0x4c, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x43, 0x41, 0x43, 0x48, 0x45, 0x5f, - 0x43, 0x41, 0x4e, 0x54, 0x5f, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, - 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x44, 0x49, 0x53, 0x4b, 0x5f, 0x46, 0x55, 0x4c, 0x4c, 0x10, 0x02, - 0x2a, 0x41, 0x0a, 0x15, 0x4d, 0x61, 0x69, 0x6c, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, - 0x45, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x13, 0x0a, 0x0f, 0x49, 0x4d, 0x41, - 0x50, 0x5f, 0x50, 0x4f, 0x52, 0x54, 0x5f, 0x49, 0x53, 0x53, 0x55, 0x45, 0x10, 0x00, 0x12, 0x13, - 0x0a, 0x0f, 0x53, 0x4d, 0x54, 0x50, 0x5f, 0x50, 0x4f, 0x52, 0x54, 0x5f, 0x49, 0x53, 0x53, 0x55, - 0x45, 0x10, 0x01, 0x32, 0xf5, 0x21, 0x0a, 0x09, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x52, 0x70, - 0x63, 0x12, 0x40, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x50, 0x6f, - 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x18, 0x2e, 0x62, 0x72, 0x69, 0x64, - 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x08, 0x47, 0x75, 0x69, 0x52, 0x65, 0x61, 0x64, 0x79, 0x12, - 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, - 0x36, 0x0a, 0x04, 0x51, 0x75, 0x69, 0x74, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, - 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x39, 0x0a, 0x07, 0x52, 0x65, 0x73, 0x74, 0x61, - 0x72, 0x74, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x12, 0x46, 0x0a, 0x10, 0x53, 0x65, 0x74, 0x53, 0x68, 0x6f, 0x77, 0x4f, 0x6e, 0x53, - 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x43, 0x0a, 0x0d, 0x53, 0x68, - 0x6f, 0x77, 0x4f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x16, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, - 0x49, 0x0a, 0x13, 0x53, 0x65, 0x74, 0x53, 0x68, 0x6f, 0x77, 0x53, 0x70, 0x6c, 0x61, 0x73, 0x68, - 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x12, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x46, 0x0a, 0x10, 0x53, 0x68, - 0x6f, 0x77, 0x53, 0x70, 0x6c, 0x61, 0x73, 0x68, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x12, 0x16, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x12, 0x48, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x44, 0x6f, 0x63, 0x6b, 0x49, 0x63, 0x6f, - 0x6e, 0x56, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x12, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x45, 0x0a, 0x0f, - 0x44, 0x6f, 0x63, 0x6b, 0x49, 0x63, 0x6f, 0x6e, 0x56, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x12, - 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x12, 0x48, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x49, 0x73, 0x46, 0x69, 0x72, 0x73, - 0x74, 0x47, 0x75, 0x69, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x45, 0x0a, - 0x0f, 0x49, 0x73, 0x46, 0x69, 0x72, 0x73, 0x74, 0x47, 0x75, 0x69, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x43, 0x0a, + 0x0e, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x48, 0x00, 0x52, 0x0e, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x64, 0x12, 0x55, 0x0a, 0x14, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x43, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x64, 0x4c, 0x6f, 0x67, 0x6f, 0x75, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1f, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x43, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x4c, 0x6f, 0x67, 0x6f, 0x75, 0x74, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x48, 0x00, 0x52, 0x14, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x43, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x64, 0x4c, 0x6f, 0x67, 0x6f, 0x75, 0x74, 0x12, 0x3d, 0x0a, 0x0c, 0x61, 0x70, 0x69, + 0x43, 0x65, 0x72, 0x74, 0x49, 0x73, 0x73, 0x75, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x17, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x70, 0x69, 0x43, 0x65, 0x72, 0x74, 0x49, 0x73, + 0x73, 0x75, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0c, 0x61, 0x70, 0x69, 0x43, + 0x65, 0x72, 0x74, 0x49, 0x73, 0x73, 0x75, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x22, 0x34, 0x0a, 0x1c, 0x4e, 0x6f, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x4b, 0x65, 0x79, + 0x46, 0x6f, 0x72, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x2f, 0x0a, 0x13, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x18, + 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x35, 0x0a, 0x19, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x4c, 0x6f, 0x67, 0x6f, 0x75, 0x74, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, + 0x13, 0x0a, 0x11, 0x41, 0x70, 0x69, 0x43, 0x65, 0x72, 0x74, 0x49, 0x73, 0x73, 0x75, 0x65, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x22, 0xfb, 0x01, 0x0a, 0x09, 0x55, 0x73, 0x65, 0x72, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x12, 0x5e, 0x0a, 0x17, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x53, 0x70, 0x6c, 0x69, + 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x6f, 0x67, 0x67, 0x6c, + 0x65, 0x53, 0x70, 0x6c, 0x69, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, + 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x17, 0x74, 0x6f, 0x67, 0x67, 0x6c, + 0x65, 0x53, 0x70, 0x6c, 0x69, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, + 0x65, 0x64, 0x12, 0x49, 0x0a, 0x10, 0x75, 0x73, 0x65, 0x72, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, + 0x72, 0x70, 0x63, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x10, 0x75, 0x73, 0x65, + 0x72, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x3a, 0x0a, + 0x0b, 0x75, 0x73, 0x65, 0x72, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0b, 0x75, 0x73, + 0x65, 0x72, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x22, 0x36, 0x0a, 0x1c, 0x54, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x53, 0x70, 0x6c, 0x69, + 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x44, 0x22, 0x33, 0x0a, 0x15, 0x55, 0x73, + 0x65, 0x72, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, + 0x2a, 0x0a, 0x10, 0x55, 0x73, 0x65, 0x72, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x44, 0x2a, 0xa2, 0x01, 0x0a, 0x0e, + 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, + 0x0a, 0x17, 0x55, 0x53, 0x45, 0x52, 0x4e, 0x41, 0x4d, 0x45, 0x5f, 0x50, 0x41, 0x53, 0x53, 0x57, + 0x4f, 0x52, 0x44, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x46, + 0x52, 0x45, 0x45, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x43, 0x4f, + 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, + 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x46, 0x41, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x12, + 0x0d, 0x0a, 0x09, 0x54, 0x46, 0x41, 0x5f, 0x41, 0x42, 0x4f, 0x52, 0x54, 0x10, 0x04, 0x12, 0x17, + 0x0a, 0x13, 0x54, 0x57, 0x4f, 0x5f, 0x50, 0x41, 0x53, 0x53, 0x57, 0x4f, 0x52, 0x44, 0x53, 0x5f, + 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x05, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x57, 0x4f, 0x5f, 0x50, + 0x41, 0x53, 0x53, 0x57, 0x4f, 0x52, 0x44, 0x53, 0x5f, 0x41, 0x42, 0x4f, 0x52, 0x54, 0x10, 0x06, + 0x2a, 0x5b, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x13, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x4d, 0x41, + 0x4e, 0x55, 0x41, 0x4c, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, + 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x5f, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x53, + 0x49, 0x4c, 0x45, 0x4e, 0x54, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x2a, 0x57, 0x0a, + 0x0e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x1b, 0x0a, 0x17, 0x43, 0x41, 0x43, 0x48, 0x45, 0x5f, 0x55, 0x4e, 0x41, 0x56, 0x41, 0x49, 0x4c, + 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, + 0x43, 0x41, 0x43, 0x48, 0x45, 0x5f, 0x43, 0x41, 0x4e, 0x54, 0x5f, 0x4d, 0x4f, 0x56, 0x45, 0x5f, + 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x44, 0x49, 0x53, 0x4b, 0x5f, + 0x46, 0x55, 0x4c, 0x4c, 0x10, 0x02, 0x2a, 0x41, 0x0a, 0x15, 0x4d, 0x61, 0x69, 0x6c, 0x53, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x13, 0x0a, 0x0f, 0x49, 0x4d, 0x41, 0x50, 0x5f, 0x50, 0x4f, 0x52, 0x54, 0x5f, 0x49, 0x53, 0x53, + 0x55, 0x45, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x4d, 0x54, 0x50, 0x5f, 0x50, 0x4f, 0x52, + 0x54, 0x5f, 0x49, 0x53, 0x53, 0x55, 0x45, 0x10, 0x01, 0x32, 0x9f, 0x1b, 0x0a, 0x06, 0x42, 0x72, + 0x69, 0x64, 0x67, 0x65, 0x12, 0x3a, 0x0a, 0x08, 0x47, 0x75, 0x69, 0x52, 0x65, 0x61, 0x64, 0x79, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x12, 0x46, 0x0a, 0x10, 0x53, 0x65, 0x74, 0x49, 0x73, 0x41, 0x75, 0x74, - 0x6f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4f, 0x6e, 0x12, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x43, 0x0a, 0x0d, - 0x49, 0x73, 0x41, 0x75, 0x74, 0x6f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4f, 0x6e, 0x12, 0x16, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x12, 0x46, 0x0a, 0x10, 0x53, 0x65, 0x74, 0x49, 0x73, 0x42, 0x65, 0x74, 0x61, 0x45, 0x6e, - 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x43, 0x0a, 0x0d, 0x49, 0x73, 0x42, - 0x65, 0x74, 0x61, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x1a, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3c, - 0x0a, 0x04, 0x47, 0x6f, 0x4f, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3e, 0x0a, 0x0c, - 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x65, 0x73, 0x65, 0x74, 0x12, 0x16, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3f, 0x0a, 0x07, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, - 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3f, 0x0a, - 0x07, 0x4c, 0x6f, 0x67, 0x50, 0x61, 0x74, 0x68, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x12, 0x36, 0x0a, 0x04, 0x51, 0x75, 0x69, 0x74, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x43, - 0x0a, 0x0b, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x16, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x12, 0x48, 0x0a, 0x10, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x4e, 0x6f, - 0x74, 0x65, 0x73, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, - 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x47, 0x0a, - 0x0f, 0x4c, 0x61, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x50, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x6e, 0x6b, - 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x4a, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x6c, - 0x6f, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x12, 0x47, 0x0a, 0x0f, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, - 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x4d, 0x0a, 0x15, 0x53, - 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x43, 0x6c, - 0x69, 0x65, 0x6e, 0x74, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4a, 0x0a, 0x12, 0x43, 0x75, - 0x72, 0x72, 0x65, 0x6e, 0x74, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x40, 0x0a, 0x09, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x42, 0x75, 0x67, 0x12, 0x1b, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, - 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x75, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x38, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x69, - 0x6e, 0x12, 0x17, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, - 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x12, 0x3b, 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x32, 0x46, 0x41, 0x12, 0x17, - 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, - 0x42, 0x0a, 0x0f, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x32, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, - 0x64, 0x73, 0x12, 0x17, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x4c, - 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, + 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x39, 0x0a, 0x07, 0x52, 0x65, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x12, 0x42, 0x0a, 0x0a, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x41, 0x62, 0x6f, 0x72, - 0x74, 0x12, 0x1c, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, - 0x67, 0x69, 0x6e, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3d, 0x0a, 0x0b, 0x43, 0x68, 0x65, 0x63, 0x6b, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3f, 0x0a, 0x0d, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, - 0x6c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, - 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4c, 0x0a, 0x16, 0x53, 0x65, 0x74, 0x49, 0x73, - 0x41, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4f, - 0x6e, 0x12, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x49, 0x0a, 0x13, 0x49, 0x73, 0x41, 0x75, 0x74, 0x6f, 0x6d, - 0x61, 0x74, 0x69, 0x63, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4f, 0x6e, 0x12, 0x16, 0x2e, 0x67, + 0x70, 0x74, 0x79, 0x12, 0x43, 0x0a, 0x0d, 0x53, 0x68, 0x6f, 0x77, 0x4f, 0x6e, 0x53, 0x74, 0x61, + 0x72, 0x74, 0x75, 0x70, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, + 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x46, 0x0a, 0x10, 0x53, 0x68, 0x6f, 0x77, + 0x53, 0x70, 0x6c, 0x61, 0x73, 0x68, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x12, 0x4d, 0x0a, 0x17, 0x53, 0x65, 0x74, 0x49, 0x73, 0x43, 0x61, 0x63, 0x68, 0x65, 0x4f, 0x6e, - 0x44, 0x69, 0x73, 0x6b, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x1a, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, - 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, - 0x4a, 0x0a, 0x14, 0x49, 0x73, 0x43, 0x61, 0x63, 0x68, 0x65, 0x4f, 0x6e, 0x44, 0x69, 0x73, 0x6b, - 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, - 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x48, 0x0a, 0x10, 0x53, - 0x65, 0x74, 0x44, 0x69, 0x73, 0x6b, 0x43, 0x61, 0x63, 0x68, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, - 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x45, 0x0a, 0x0d, 0x44, 0x69, 0x73, 0x6b, 0x43, 0x61, 0x63, - 0x68, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x4e, 0x0a, 0x10, - 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x61, 0x63, 0x68, 0x65, - 0x12, 0x22, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x61, 0x63, 0x68, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x45, 0x0a, 0x0f, - 0x53, 0x65, 0x74, 0x49, 0x73, 0x44, 0x6f, 0x48, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, - 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x12, 0x42, 0x0a, 0x0c, 0x49, 0x73, 0x44, 0x6f, 0x48, 0x45, 0x6e, 0x61, 0x62, - 0x6c, 0x65, 0x64, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x12, 0x45, 0x0a, 0x0f, 0x49, 0x73, 0x46, 0x69, 0x72, 0x73, 0x74, 0x47, 0x75, 0x69, 0x53, 0x74, + 0x61, 0x72, 0x74, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, - 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x46, 0x0a, 0x10, 0x53, 0x65, 0x74, 0x55, 0x73, - 0x65, 0x53, 0x73, 0x6c, 0x46, 0x6f, 0x72, 0x53, 0x6d, 0x74, 0x70, 0x12, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x46, 0x0a, 0x10, 0x53, 0x65, 0x74, 0x49, 0x73, + 0x41, 0x75, 0x74, 0x6f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4f, 0x6e, 0x12, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, - 0x43, 0x0a, 0x0d, 0x55, 0x73, 0x65, 0x53, 0x73, 0x6c, 0x46, 0x6f, 0x72, 0x53, 0x6d, 0x74, 0x70, + 0x43, 0x0a, 0x0d, 0x49, 0x73, 0x41, 0x75, 0x74, 0x6f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4f, 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x12, 0x40, 0x0a, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x42, 0x0a, 0x0b, 0x53, 0x65, 0x74, 0x49, 0x6d, 0x61, - 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3f, 0x0a, 0x08, 0x49, 0x6d, - 0x61, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1b, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x42, 0x0a, 0x0b, 0x53, - 0x65, 0x74, 0x53, 0x6d, 0x74, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, - 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x61, 0x6c, 0x75, 0x65, 0x12, 0x46, 0x0a, 0x10, 0x53, 0x65, 0x74, 0x49, 0x73, 0x42, 0x65, 0x74, + 0x61, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x43, 0x0a, 0x0d, + 0x49, 0x73, 0x42, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x16, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x12, 0x3c, 0x0a, 0x04, 0x47, 0x6f, 0x4f, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, + 0x3e, 0x0a, 0x0c, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x65, 0x73, 0x65, 0x74, 0x12, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, - 0x3f, 0x0a, 0x08, 0x53, 0x6d, 0x74, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x16, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x1a, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x12, 0x44, 0x0a, 0x0b, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x12, - 0x1d, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x45, 0x0a, 0x0a, 0x49, 0x73, 0x50, 0x6f, 0x72, 0x74, - 0x46, 0x72, 0x65, 0x65, 0x12, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x1a, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x53, 0x0a, - 0x12, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x25, 0x2e, 0x62, 0x72, - 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, - 0x65, 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, - 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x47, - 0x0a, 0x0f, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x3f, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x12, 0x40, 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x73, 0x50, 0x61, 0x74, 0x68, 0x12, 0x16, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, + 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x12, 0x43, 0x0a, 0x0b, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x50, 0x61, 0x74, + 0x68, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, - 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x42, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x55, 0x73, - 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1b, - 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4c, - 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x07, 0x47, - 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0f, - 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x12, - 0x4b, 0x0a, 0x10, 0x53, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x53, 0x70, 0x6c, 0x69, 0x74, 0x4d, - 0x6f, 0x64, 0x65, 0x12, 0x1f, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, + 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x4e, 0x0a, 0x16, 0x44, 0x65, 0x70, 0x65, 0x6e, + 0x64, 0x65, 0x6e, 0x63, 0x79, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x4c, 0x69, 0x6e, + 0x6b, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x4a, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x43, 0x6f, + 0x6c, 0x6f, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x12, 0x47, 0x0a, 0x0f, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x4a, 0x0a, 0x12, + 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x43, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3b, 0x0a, 0x09, 0x52, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x42, 0x75, 0x67, 0x12, 0x16, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x42, 0x75, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x33, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x12, + 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x36, 0x0a, 0x08, 0x4c, 0x6f, + 0x67, 0x69, 0x6e, 0x32, 0x46, 0x41, 0x12, 0x12, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, + 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x12, 0x3d, 0x0a, 0x0f, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x32, 0x50, 0x61, 0x73, 0x73, + 0x77, 0x6f, 0x72, 0x64, 0x73, 0x12, 0x12, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x67, + 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x12, 0x3d, 0x0a, 0x0a, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x12, + 0x17, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x41, 0x62, 0x6f, 0x72, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x12, 0x3d, 0x0a, 0x0b, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, + 0x3f, 0x0a, 0x0d, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x12, 0x4c, 0x0a, 0x16, 0x53, 0x65, 0x74, 0x49, 0x73, 0x41, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, + 0x69, 0x63, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4f, 0x6e, 0x12, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, + 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x49, + 0x0a, 0x13, 0x49, 0x73, 0x41, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x4f, 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x4a, 0x0a, 0x14, 0x49, 0x73, 0x43, + 0x61, 0x63, 0x68, 0x65, 0x4f, 0x6e, 0x44, 0x69, 0x73, 0x6b, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x64, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x45, 0x0a, 0x0d, 0x44, 0x69, 0x73, 0x6b, 0x43, 0x61, 0x63, + 0x68, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x49, 0x0a, 0x10, + 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x61, 0x63, 0x68, 0x65, + 0x12, 0x1d, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4c, 0x6f, + 0x63, 0x61, 0x6c, 0x43, 0x61, 0x63, 0x68, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x45, 0x0a, 0x0f, 0x53, 0x65, 0x74, 0x49, 0x73, + 0x44, 0x6f, 0x48, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, + 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x42, + 0x0a, 0x0c, 0x49, 0x73, 0x44, 0x6f, 0x48, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x16, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x12, 0x46, 0x0a, 0x10, 0x53, 0x65, 0x74, 0x55, 0x73, 0x65, 0x53, 0x73, 0x6c, 0x46, + 0x6f, 0x72, 0x53, 0x6d, 0x74, 0x70, 0x12, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x43, 0x0a, 0x0d, 0x55, 0x73, + 0x65, 0x53, 0x73, 0x6c, 0x46, 0x6f, 0x72, 0x53, 0x6d, 0x74, 0x70, 0x12, 0x16, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, + 0x40, 0x0a, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x12, 0x3f, 0x0a, 0x08, 0x49, 0x6d, 0x61, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x16, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x12, 0x3f, 0x0a, 0x08, 0x53, 0x6d, 0x74, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x16, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x12, 0x3f, 0x0a, 0x0b, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x6f, 0x72, + 0x74, 0x73, 0x12, 0x18, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x50, 0x6f, 0x72, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, + 0x6d, 0x70, 0x74, 0x79, 0x12, 0x45, 0x0a, 0x0a, 0x49, 0x73, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x72, + 0x65, 0x65, 0x12, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, + 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x4e, 0x0a, 0x12, 0x41, + 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x20, 0x2e, 0x67, 0x72, 0x70, 0x63, + 0x2e, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, + 0x69, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x12, 0x53, + 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x47, 0x0a, 0x0f, 0x43, 0x75, 0x72, 0x72, 0x65, + 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x12, 0x3d, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x55, + 0x73, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x33, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x0a, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, + 0x55, 0x73, 0x65, 0x72, 0x12, 0x46, 0x0a, 0x10, 0x53, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x53, + 0x70, 0x6c, 0x69, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x1a, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x53, 0x70, 0x6c, 0x69, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x42, 0x0a, 0x0a, @@ -4093,299 +4117,272 @@ var file_bridge_rpc_proto_rawDesc = []byte{ 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x12, 0x56, 0x0a, 0x16, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, - 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x4d, 0x61, 0x69, 0x6c, 0x12, 0x24, - 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x75, 0x72, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x4d, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3d, 0x0a, 0x09, - 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x1a, 0x16, 0x2e, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x42, 0x32, 0x5a, 0x30, 0x67, + 0x6d, 0x70, 0x74, 0x79, 0x12, 0x51, 0x0a, 0x16, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, + 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x4d, 0x61, 0x69, 0x6c, 0x12, 0x1f, + 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x41, + 0x70, 0x70, 0x6c, 0x65, 0x4d, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3f, 0x0a, 0x10, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x16, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x1a, 0x11, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x12, 0x41, 0x0a, 0x0f, 0x53, 0x74, 0x6f, 0x70, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x16, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x33, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x6e, 0x4d, 0x61, 0x69, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x6e, 0x2d, 0x62, 0x72, 0x69, 0x64, - 0x67, 0x65, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x72, 0x70, 0x63, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x67, 0x65, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67, 0x72, 0x70, 0x63, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( - file_bridge_rpc_proto_rawDescOnce sync.Once - file_bridge_rpc_proto_rawDescData = file_bridge_rpc_proto_rawDesc + file_bridge_proto_rawDescOnce sync.Once + file_bridge_proto_rawDescData = file_bridge_proto_rawDesc ) -func file_bridge_rpc_proto_rawDescGZIP() []byte { - file_bridge_rpc_proto_rawDescOnce.Do(func() { - file_bridge_rpc_proto_rawDescData = protoimpl.X.CompressGZIP(file_bridge_rpc_proto_rawDescData) +func file_bridge_proto_rawDescGZIP() []byte { + file_bridge_proto_rawDescOnce.Do(func() { + file_bridge_proto_rawDescData = protoimpl.X.CompressGZIP(file_bridge_proto_rawDescData) }) - return file_bridge_rpc_proto_rawDescData + return file_bridge_proto_rawDescData } -var file_bridge_rpc_proto_enumTypes = make([]protoimpl.EnumInfo, 4) -var file_bridge_rpc_proto_msgTypes = make([]protoimpl.MessageInfo, 54) -var file_bridge_rpc_proto_goTypes = []interface{}{ - (LoginErrorType)(0), // 0: bridgerpc.LoginErrorType - (UpdateErrorType)(0), // 1: bridgerpc.UpdateErrorType - (CacheErrorType)(0), // 2: bridgerpc.CacheErrorType - (MailSettingsErrorType)(0), // 3: bridgerpc.MailSettingsErrorType - (*PointResponse)(nil), // 4: bridgerpc.PointResponse - (*ReportBugRequest)(nil), // 5: bridgerpc.ReportBugRequest - (*LoginRequest)(nil), // 6: bridgerpc.LoginRequest - (*LoginAbortRequest)(nil), // 7: bridgerpc.LoginAbortRequest - (*ChangeLocalCacheRequest)(nil), // 8: bridgerpc.ChangeLocalCacheRequest - (*ChangePortsRequest)(nil), // 9: bridgerpc.ChangePortsRequest - (*AvailableKeychainsResponse)(nil), // 10: bridgerpc.AvailableKeychainsResponse - (*User)(nil), // 11: bridgerpc.User - (*UserSplitModeRequest)(nil), // 12: bridgerpc.UserSplitModeRequest - (*UserListResponse)(nil), // 13: bridgerpc.UserListResponse - (*ConfigureAppleMailRequest)(nil), // 14: bridgerpc.ConfigureAppleMailRequest - (*StreamEvent)(nil), // 15: bridgerpc.StreamEvent - (*AppEvent)(nil), // 16: bridgerpc.AppEvent - (*InternetStatusEvent)(nil), // 17: bridgerpc.InternetStatusEvent - (*AutostartFinishedEvent)(nil), // 18: bridgerpc.AutostartFinishedEvent - (*ResetFinishedEvent)(nil), // 19: bridgerpc.ResetFinishedEvent - (*ReportBugFinishedEvent)(nil), // 20: bridgerpc.ReportBugFinishedEvent - (*ReportBugSuccessEvent)(nil), // 21: bridgerpc.ReportBugSuccessEvent - (*ReportBugErrorEvent)(nil), // 22: bridgerpc.ReportBugErrorEvent - (*ShowMainWindowEvent)(nil), // 23: bridgerpc.ShowMainWindowEvent - (*LoginEvent)(nil), // 24: bridgerpc.LoginEvent - (*LoginErrorEvent)(nil), // 25: bridgerpc.LoginErrorEvent - (*LoginTfaRequestedEvent)(nil), // 26: bridgerpc.LoginTfaRequestedEvent - (*LoginTwoPasswordsRequestedEvent)(nil), // 27: bridgerpc.LoginTwoPasswordsRequestedEvent - (*LoginFinishedEvent)(nil), // 28: bridgerpc.LoginFinishedEvent - (*UpdateEvent)(nil), // 29: bridgerpc.UpdateEvent - (*UpdateErrorEvent)(nil), // 30: bridgerpc.UpdateErrorEvent - (*UpdateManualReadyEvent)(nil), // 31: bridgerpc.UpdateManualReadyEvent - (*UpdateManualRestartNeededEvent)(nil), // 32: bridgerpc.UpdateManualRestartNeededEvent - (*UpdateForceEvent)(nil), // 33: bridgerpc.UpdateForceEvent - (*UpdateSilentRestartNeeded)(nil), // 34: bridgerpc.UpdateSilentRestartNeeded - (*UpdateIsLatestVersion)(nil), // 35: bridgerpc.UpdateIsLatestVersion - (*UpdateCheckFinished)(nil), // 36: bridgerpc.UpdateCheckFinished - (*CacheEvent)(nil), // 37: bridgerpc.CacheEvent - (*CacheErrorEvent)(nil), // 38: bridgerpc.CacheErrorEvent - (*CacheLocationChangeSuccessEvent)(nil), // 39: bridgerpc.CacheLocationChangeSuccessEvent - (*ChangeLocalCacheFinishedEvent)(nil), // 40: bridgerpc.ChangeLocalCacheFinishedEvent - (*MailSettingsEvent)(nil), // 41: bridgerpc.MailSettingsEvent - (*MailSettingsErrorEvent)(nil), // 42: bridgerpc.MailSettingsErrorEvent - (*UseSslForSmtpFinishedEvent)(nil), // 43: bridgerpc.UseSslForSmtpFinishedEvent - (*ChangePortsFinishedEvent)(nil), // 44: bridgerpc.ChangePortsFinishedEvent - (*KeychainEvent)(nil), // 45: bridgerpc.KeychainEvent - (*ChangeKeychainFinishedEvent)(nil), // 46: bridgerpc.ChangeKeychainFinishedEvent - (*HasNoKeychainEvent)(nil), // 47: bridgerpc.HasNoKeychainEvent - (*RebuildKeychainEvent)(nil), // 48: bridgerpc.RebuildKeychainEvent - (*MailEvent)(nil), // 49: bridgerpc.MailEvent - (*NoActiveKeyForRecipientEvent)(nil), // 50: bridgerpc.NoActiveKeyForRecipientEvent - (*AddressChangedEvent)(nil), // 51: bridgerpc.AddressChangedEvent - (*AddressChangedLogoutEvent)(nil), // 52: bridgerpc.AddressChangedLogoutEvent - (*ApiCertIssueEvent)(nil), // 53: bridgerpc.ApiCertIssueEvent - (*UserEvent)(nil), // 54: bridgerpc.UserEvent - (*ToggleSplitModeFinishedEvent)(nil), // 55: bridgerpc.ToggleSplitModeFinishedEvent - (*UserDisconnectedEvent)(nil), // 56: bridgerpc.UserDisconnectedEvent - (*UserChangedEvent)(nil), // 57: bridgerpc.UserChangedEvent - (*emptypb.Empty)(nil), // 58: google.protobuf.Empty - (*wrapperspb.BoolValue)(nil), // 59: google.protobuf.BoolValue - (*wrapperspb.StringValue)(nil), // 60: google.protobuf.StringValue - (*wrapperspb.Int32Value)(nil), // 61: google.protobuf.Int32Value +var file_bridge_proto_enumTypes = make([]protoimpl.EnumInfo, 4) +var file_bridge_proto_msgTypes = make([]protoimpl.MessageInfo, 55) +var file_bridge_proto_goTypes = []interface{}{ + (LoginErrorType)(0), // 0: grpc.LoginErrorType + (UpdateErrorType)(0), // 1: grpc.UpdateErrorType + (CacheErrorType)(0), // 2: grpc.CacheErrorType + (MailSettingsErrorType)(0), // 3: grpc.MailSettingsErrorType + (*ReportBugRequest)(nil), // 4: grpc.ReportBugRequest + (*LoginRequest)(nil), // 5: grpc.LoginRequest + (*LoginAbortRequest)(nil), // 6: grpc.LoginAbortRequest + (*ChangeLocalCacheRequest)(nil), // 7: grpc.ChangeLocalCacheRequest + (*ChangePortsRequest)(nil), // 8: grpc.ChangePortsRequest + (*AvailableKeychainsResponse)(nil), // 9: grpc.AvailableKeychainsResponse + (*User)(nil), // 10: grpc.User + (*UserSplitModeRequest)(nil), // 11: grpc.UserSplitModeRequest + (*UserListResponse)(nil), // 12: grpc.UserListResponse + (*ConfigureAppleMailRequest)(nil), // 13: grpc.ConfigureAppleMailRequest + (*StreamEvent)(nil), // 14: grpc.StreamEvent + (*AppEvent)(nil), // 15: grpc.AppEvent + (*InternetStatusEvent)(nil), // 16: grpc.InternetStatusEvent + (*ToggleAutostartFinishedEvent)(nil), // 17: grpc.ToggleAutostartFinishedEvent + (*ResetFinishedEvent)(nil), // 18: grpc.ResetFinishedEvent + (*ReportBugFinishedEvent)(nil), // 19: grpc.ReportBugFinishedEvent + (*ReportBugSuccessEvent)(nil), // 20: grpc.ReportBugSuccessEvent + (*ReportBugErrorEvent)(nil), // 21: grpc.ReportBugErrorEvent + (*ShowMainWindowEvent)(nil), // 22: grpc.ShowMainWindowEvent + (*LoginEvent)(nil), // 23: grpc.LoginEvent + (*LoginErrorEvent)(nil), // 24: grpc.LoginErrorEvent + (*LoginTfaRequestedEvent)(nil), // 25: grpc.LoginTfaRequestedEvent + (*LoginTwoPasswordsRequestedEvent)(nil), // 26: grpc.LoginTwoPasswordsRequestedEvent + (*LoginFinishedEvent)(nil), // 27: grpc.LoginFinishedEvent + (*UpdateEvent)(nil), // 28: grpc.UpdateEvent + (*UpdateErrorEvent)(nil), // 29: grpc.UpdateErrorEvent + (*UpdateManualReadyEvent)(nil), // 30: grpc.UpdateManualReadyEvent + (*UpdateManualRestartNeededEvent)(nil), // 31: grpc.UpdateManualRestartNeededEvent + (*UpdateForceEvent)(nil), // 32: grpc.UpdateForceEvent + (*UpdateSilentRestartNeeded)(nil), // 33: grpc.UpdateSilentRestartNeeded + (*UpdateIsLatestVersion)(nil), // 34: grpc.UpdateIsLatestVersion + (*UpdateCheckFinished)(nil), // 35: grpc.UpdateCheckFinished + (*CacheEvent)(nil), // 36: grpc.CacheEvent + (*CacheErrorEvent)(nil), // 37: grpc.CacheErrorEvent + (*CacheLocationChangeSuccessEvent)(nil), // 38: grpc.CacheLocationChangeSuccessEvent + (*ChangeLocalCacheFinishedEvent)(nil), // 39: grpc.ChangeLocalCacheFinishedEvent + (*IsCacheOnDiskEnabledChanged)(nil), // 40: grpc.IsCacheOnDiskEnabledChanged + (*DiskCachePathChanged)(nil), // 41: grpc.DiskCachePathChanged + (*MailSettingsEvent)(nil), // 42: grpc.MailSettingsEvent + (*MailSettingsErrorEvent)(nil), // 43: grpc.MailSettingsErrorEvent + (*UseSslForSmtpFinishedEvent)(nil), // 44: grpc.UseSslForSmtpFinishedEvent + (*ChangePortsFinishedEvent)(nil), // 45: grpc.ChangePortsFinishedEvent + (*KeychainEvent)(nil), // 46: grpc.KeychainEvent + (*ChangeKeychainFinishedEvent)(nil), // 47: grpc.ChangeKeychainFinishedEvent + (*HasNoKeychainEvent)(nil), // 48: grpc.HasNoKeychainEvent + (*RebuildKeychainEvent)(nil), // 49: grpc.RebuildKeychainEvent + (*MailEvent)(nil), // 50: grpc.MailEvent + (*NoActiveKeyForRecipientEvent)(nil), // 51: grpc.NoActiveKeyForRecipientEvent + (*AddressChangedEvent)(nil), // 52: grpc.AddressChangedEvent + (*AddressChangedLogoutEvent)(nil), // 53: grpc.AddressChangedLogoutEvent + (*ApiCertIssueEvent)(nil), // 54: grpc.ApiCertIssueEvent + (*UserEvent)(nil), // 55: grpc.UserEvent + (*ToggleSplitModeFinishedEvent)(nil), // 56: grpc.ToggleSplitModeFinishedEvent + (*UserDisconnectedEvent)(nil), // 57: grpc.UserDisconnectedEvent + (*UserChangedEvent)(nil), // 58: grpc.UserChangedEvent + (*emptypb.Empty)(nil), // 59: google.protobuf.Empty + (*wrapperspb.BoolValue)(nil), // 60: google.protobuf.BoolValue + (*wrapperspb.StringValue)(nil), // 61: google.protobuf.StringValue + (*wrapperspb.Int32Value)(nil), // 62: google.protobuf.Int32Value } -var file_bridge_rpc_proto_depIdxs = []int32{ - 11, // 0: bridgerpc.UserListResponse.users:type_name -> bridgerpc.User - 16, // 1: bridgerpc.StreamEvent.app:type_name -> bridgerpc.AppEvent - 24, // 2: bridgerpc.StreamEvent.login:type_name -> bridgerpc.LoginEvent - 29, // 3: bridgerpc.StreamEvent.update:type_name -> bridgerpc.UpdateEvent - 37, // 4: bridgerpc.StreamEvent.cache:type_name -> bridgerpc.CacheEvent - 41, // 5: bridgerpc.StreamEvent.mailSettings:type_name -> bridgerpc.MailSettingsEvent - 45, // 6: bridgerpc.StreamEvent.keychain:type_name -> bridgerpc.KeychainEvent - 49, // 7: bridgerpc.StreamEvent.mail:type_name -> bridgerpc.MailEvent - 54, // 8: bridgerpc.StreamEvent.user:type_name -> bridgerpc.UserEvent - 17, // 9: bridgerpc.AppEvent.internetStatus:type_name -> bridgerpc.InternetStatusEvent - 18, // 10: bridgerpc.AppEvent.autostartFinished:type_name -> bridgerpc.AutostartFinishedEvent - 19, // 11: bridgerpc.AppEvent.resetFinished:type_name -> bridgerpc.ResetFinishedEvent - 20, // 12: bridgerpc.AppEvent.reportBugFinished:type_name -> bridgerpc.ReportBugFinishedEvent - 21, // 13: bridgerpc.AppEvent.reportBugSuccess:type_name -> bridgerpc.ReportBugSuccessEvent - 22, // 14: bridgerpc.AppEvent.reportBugError:type_name -> bridgerpc.ReportBugErrorEvent - 23, // 15: bridgerpc.AppEvent.showMainWindow:type_name -> bridgerpc.ShowMainWindowEvent - 25, // 16: bridgerpc.LoginEvent.error:type_name -> bridgerpc.LoginErrorEvent - 26, // 17: bridgerpc.LoginEvent.tfaRequested:type_name -> bridgerpc.LoginTfaRequestedEvent - 27, // 18: bridgerpc.LoginEvent.twoPasswordRequested:type_name -> bridgerpc.LoginTwoPasswordsRequestedEvent - 28, // 19: bridgerpc.LoginEvent.finished:type_name -> bridgerpc.LoginFinishedEvent - 0, // 20: bridgerpc.LoginErrorEvent.type:type_name -> bridgerpc.LoginErrorType - 30, // 21: bridgerpc.UpdateEvent.error:type_name -> bridgerpc.UpdateErrorEvent - 31, // 22: bridgerpc.UpdateEvent.manualReady:type_name -> bridgerpc.UpdateManualReadyEvent - 32, // 23: bridgerpc.UpdateEvent.manualRestartNeeded:type_name -> bridgerpc.UpdateManualRestartNeededEvent - 33, // 24: bridgerpc.UpdateEvent.force:type_name -> bridgerpc.UpdateForceEvent - 34, // 25: bridgerpc.UpdateEvent.silentRestartNeeded:type_name -> bridgerpc.UpdateSilentRestartNeeded - 35, // 26: bridgerpc.UpdateEvent.isLatestVersion:type_name -> bridgerpc.UpdateIsLatestVersion - 36, // 27: bridgerpc.UpdateEvent.checkFinished:type_name -> bridgerpc.UpdateCheckFinished - 1, // 28: bridgerpc.UpdateErrorEvent.type:type_name -> bridgerpc.UpdateErrorType - 38, // 29: bridgerpc.CacheEvent.error:type_name -> bridgerpc.CacheErrorEvent - 39, // 30: bridgerpc.CacheEvent.locationChangedSuccess:type_name -> bridgerpc.CacheLocationChangeSuccessEvent - 40, // 31: bridgerpc.CacheEvent.changeLocalCacheFinished:type_name -> bridgerpc.ChangeLocalCacheFinishedEvent - 2, // 32: bridgerpc.CacheErrorEvent.type:type_name -> bridgerpc.CacheErrorType - 42, // 33: bridgerpc.MailSettingsEvent.error:type_name -> bridgerpc.MailSettingsErrorEvent - 43, // 34: bridgerpc.MailSettingsEvent.useSslForSmtpFinished:type_name -> bridgerpc.UseSslForSmtpFinishedEvent - 44, // 35: bridgerpc.MailSettingsEvent.changePortsFinished:type_name -> bridgerpc.ChangePortsFinishedEvent - 3, // 36: bridgerpc.MailSettingsErrorEvent.type:type_name -> bridgerpc.MailSettingsErrorType - 46, // 37: bridgerpc.KeychainEvent.changeKeychainFinished:type_name -> bridgerpc.ChangeKeychainFinishedEvent - 47, // 38: bridgerpc.KeychainEvent.hasNoKeychain:type_name -> bridgerpc.HasNoKeychainEvent - 48, // 39: bridgerpc.KeychainEvent.rebuildKeychain:type_name -> bridgerpc.RebuildKeychainEvent - 50, // 40: bridgerpc.MailEvent.noActiveKeyForRecipientEvent:type_name -> bridgerpc.NoActiveKeyForRecipientEvent - 51, // 41: bridgerpc.MailEvent.addressChanged:type_name -> bridgerpc.AddressChangedEvent - 52, // 42: bridgerpc.MailEvent.addressChangedLogout:type_name -> bridgerpc.AddressChangedLogoutEvent - 53, // 43: bridgerpc.MailEvent.apiCertIssue:type_name -> bridgerpc.ApiCertIssueEvent - 55, // 44: bridgerpc.UserEvent.toggleSplitModeFinished:type_name -> bridgerpc.ToggleSplitModeFinishedEvent - 56, // 45: bridgerpc.UserEvent.userDisconnected:type_name -> bridgerpc.UserDisconnectedEvent - 57, // 46: bridgerpc.UserEvent.userChanged:type_name -> bridgerpc.UserChangedEvent - 11, // 47: bridgerpc.UserChangedEvent.user:type_name -> bridgerpc.User - 58, // 48: bridgerpc.BridgeRpc.GetCursorPos:input_type -> google.protobuf.Empty - 58, // 49: bridgerpc.BridgeRpc.GuiReady:input_type -> google.protobuf.Empty - 58, // 50: bridgerpc.BridgeRpc.Quit:input_type -> google.protobuf.Empty - 58, // 51: bridgerpc.BridgeRpc.Restart:input_type -> google.protobuf.Empty - 59, // 52: bridgerpc.BridgeRpc.SetShowOnStartup:input_type -> google.protobuf.BoolValue - 58, // 53: bridgerpc.BridgeRpc.ShowOnStartup:input_type -> google.protobuf.Empty - 59, // 54: bridgerpc.BridgeRpc.SetShowSplashScreen:input_type -> google.protobuf.BoolValue - 58, // 55: bridgerpc.BridgeRpc.ShowSplashScreen:input_type -> google.protobuf.Empty - 59, // 56: bridgerpc.BridgeRpc.SetDockIconVisible:input_type -> google.protobuf.BoolValue - 58, // 57: bridgerpc.BridgeRpc.DockIconVisible:input_type -> google.protobuf.Empty - 59, // 58: bridgerpc.BridgeRpc.SetIsFirstGuiStart:input_type -> google.protobuf.BoolValue - 58, // 59: bridgerpc.BridgeRpc.IsFirstGuiStart:input_type -> google.protobuf.Empty - 59, // 60: bridgerpc.BridgeRpc.SetIsAutostartOn:input_type -> google.protobuf.BoolValue - 58, // 61: bridgerpc.BridgeRpc.IsAutostartOn:input_type -> google.protobuf.Empty - 59, // 62: bridgerpc.BridgeRpc.SetIsBetaEnabled:input_type -> google.protobuf.BoolValue - 58, // 63: bridgerpc.BridgeRpc.IsBetaEnabled:input_type -> google.protobuf.Empty - 58, // 64: bridgerpc.BridgeRpc.GoOs:input_type -> google.protobuf.Empty - 58, // 65: bridgerpc.BridgeRpc.TriggerReset:input_type -> google.protobuf.Empty - 58, // 66: bridgerpc.BridgeRpc.Version:input_type -> google.protobuf.Empty - 58, // 67: bridgerpc.BridgeRpc.LogPath:input_type -> google.protobuf.Empty - 58, // 68: bridgerpc.BridgeRpc.LicensePath:input_type -> google.protobuf.Empty - 58, // 69: bridgerpc.BridgeRpc.ReleaseNotesLink:input_type -> google.protobuf.Empty - 58, // 70: bridgerpc.BridgeRpc.LandingPageLink:input_type -> google.protobuf.Empty - 60, // 71: bridgerpc.BridgeRpc.SetColorSchemeName:input_type -> google.protobuf.StringValue - 58, // 72: bridgerpc.BridgeRpc.ColorSchemeName:input_type -> google.protobuf.Empty - 60, // 73: bridgerpc.BridgeRpc.SetCurrentEmailClient:input_type -> google.protobuf.StringValue - 58, // 74: bridgerpc.BridgeRpc.CurrentEmailClient:input_type -> google.protobuf.Empty - 5, // 75: bridgerpc.BridgeRpc.ReportBug:input_type -> bridgerpc.ReportBugRequest - 6, // 76: bridgerpc.BridgeRpc.Login:input_type -> bridgerpc.LoginRequest - 6, // 77: bridgerpc.BridgeRpc.Login2FA:input_type -> bridgerpc.LoginRequest - 6, // 78: bridgerpc.BridgeRpc.Login2Passwords:input_type -> bridgerpc.LoginRequest - 7, // 79: bridgerpc.BridgeRpc.LoginAbort:input_type -> bridgerpc.LoginAbortRequest - 58, // 80: bridgerpc.BridgeRpc.CheckUpdate:input_type -> google.protobuf.Empty - 58, // 81: bridgerpc.BridgeRpc.InstallUpdate:input_type -> google.protobuf.Empty - 59, // 82: bridgerpc.BridgeRpc.SetIsAutomaticUpdateOn:input_type -> google.protobuf.BoolValue - 58, // 83: bridgerpc.BridgeRpc.IsAutomaticUpdateOn:input_type -> google.protobuf.Empty - 59, // 84: bridgerpc.BridgeRpc.SetIsCacheOnDiskEnabled:input_type -> google.protobuf.BoolValue - 58, // 85: bridgerpc.BridgeRpc.IsCacheOnDiskEnabled:input_type -> google.protobuf.Empty - 60, // 86: bridgerpc.BridgeRpc.SetDiskCachePath:input_type -> google.protobuf.StringValue - 58, // 87: bridgerpc.BridgeRpc.DiskCachePath:input_type -> google.protobuf.Empty - 8, // 88: bridgerpc.BridgeRpc.ChangeLocalCache:input_type -> bridgerpc.ChangeLocalCacheRequest - 59, // 89: bridgerpc.BridgeRpc.SetIsDoHEnabled:input_type -> google.protobuf.BoolValue - 58, // 90: bridgerpc.BridgeRpc.IsDoHEnabled:input_type -> google.protobuf.Empty - 59, // 91: bridgerpc.BridgeRpc.SetUseSslForSmtp:input_type -> google.protobuf.BoolValue - 58, // 92: bridgerpc.BridgeRpc.UseSslForSmtp:input_type -> google.protobuf.Empty - 58, // 93: bridgerpc.BridgeRpc.Hostname:input_type -> google.protobuf.Empty - 61, // 94: bridgerpc.BridgeRpc.SetImapPort:input_type -> google.protobuf.Int32Value - 58, // 95: bridgerpc.BridgeRpc.ImapPort:input_type -> google.protobuf.Empty - 61, // 96: bridgerpc.BridgeRpc.SetSmtpPort:input_type -> google.protobuf.Int32Value - 58, // 97: bridgerpc.BridgeRpc.SmtpPort:input_type -> google.protobuf.Empty - 9, // 98: bridgerpc.BridgeRpc.ChangePorts:input_type -> bridgerpc.ChangePortsRequest - 61, // 99: bridgerpc.BridgeRpc.IsPortFree:input_type -> google.protobuf.Int32Value - 58, // 100: bridgerpc.BridgeRpc.AvailableKeychains:input_type -> google.protobuf.Empty - 60, // 101: bridgerpc.BridgeRpc.SetCurrentKeychain:input_type -> google.protobuf.StringValue - 58, // 102: bridgerpc.BridgeRpc.CurrentKeychain:input_type -> google.protobuf.Empty - 58, // 103: bridgerpc.BridgeRpc.GetUserList:input_type -> google.protobuf.Empty - 58, // 104: bridgerpc.BridgeRpc.GetUser:input_type -> google.protobuf.Empty - 12, // 105: bridgerpc.BridgeRpc.SetUserSplitMode:input_type -> bridgerpc.UserSplitModeRequest - 60, // 106: bridgerpc.BridgeRpc.LogoutUser:input_type -> google.protobuf.StringValue - 60, // 107: bridgerpc.BridgeRpc.RemoveUser:input_type -> google.protobuf.StringValue - 14, // 108: bridgerpc.BridgeRpc.ConfigureUserAppleMail:input_type -> bridgerpc.ConfigureAppleMailRequest - 58, // 109: bridgerpc.BridgeRpc.GetEvents:input_type -> google.protobuf.Empty - 4, // 110: bridgerpc.BridgeRpc.GetCursorPos:output_type -> bridgerpc.PointResponse - 58, // 111: bridgerpc.BridgeRpc.GuiReady:output_type -> google.protobuf.Empty - 58, // 112: bridgerpc.BridgeRpc.Quit:output_type -> google.protobuf.Empty - 58, // 113: bridgerpc.BridgeRpc.Restart:output_type -> google.protobuf.Empty - 58, // 114: bridgerpc.BridgeRpc.SetShowOnStartup:output_type -> google.protobuf.Empty - 59, // 115: bridgerpc.BridgeRpc.ShowOnStartup:output_type -> google.protobuf.BoolValue - 58, // 116: bridgerpc.BridgeRpc.SetShowSplashScreen:output_type -> google.protobuf.Empty - 59, // 117: bridgerpc.BridgeRpc.ShowSplashScreen:output_type -> google.protobuf.BoolValue - 58, // 118: bridgerpc.BridgeRpc.SetDockIconVisible:output_type -> google.protobuf.Empty - 59, // 119: bridgerpc.BridgeRpc.DockIconVisible:output_type -> google.protobuf.BoolValue - 58, // 120: bridgerpc.BridgeRpc.SetIsFirstGuiStart:output_type -> google.protobuf.Empty - 59, // 121: bridgerpc.BridgeRpc.IsFirstGuiStart:output_type -> google.protobuf.BoolValue - 58, // 122: bridgerpc.BridgeRpc.SetIsAutostartOn:output_type -> google.protobuf.Empty - 59, // 123: bridgerpc.BridgeRpc.IsAutostartOn:output_type -> google.protobuf.BoolValue - 58, // 124: bridgerpc.BridgeRpc.SetIsBetaEnabled:output_type -> google.protobuf.Empty - 59, // 125: bridgerpc.BridgeRpc.IsBetaEnabled:output_type -> google.protobuf.BoolValue - 60, // 126: bridgerpc.BridgeRpc.GoOs:output_type -> google.protobuf.StringValue - 58, // 127: bridgerpc.BridgeRpc.TriggerReset:output_type -> google.protobuf.Empty - 60, // 128: bridgerpc.BridgeRpc.Version:output_type -> google.protobuf.StringValue - 60, // 129: bridgerpc.BridgeRpc.LogPath:output_type -> google.protobuf.StringValue - 60, // 130: bridgerpc.BridgeRpc.LicensePath:output_type -> google.protobuf.StringValue - 60, // 131: bridgerpc.BridgeRpc.ReleaseNotesLink:output_type -> google.protobuf.StringValue - 60, // 132: bridgerpc.BridgeRpc.LandingPageLink:output_type -> google.protobuf.StringValue - 58, // 133: bridgerpc.BridgeRpc.SetColorSchemeName:output_type -> google.protobuf.Empty - 60, // 134: bridgerpc.BridgeRpc.ColorSchemeName:output_type -> google.protobuf.StringValue - 58, // 135: bridgerpc.BridgeRpc.SetCurrentEmailClient:output_type -> google.protobuf.Empty - 60, // 136: bridgerpc.BridgeRpc.CurrentEmailClient:output_type -> google.protobuf.StringValue - 58, // 137: bridgerpc.BridgeRpc.ReportBug:output_type -> google.protobuf.Empty - 58, // 138: bridgerpc.BridgeRpc.Login:output_type -> google.protobuf.Empty - 58, // 139: bridgerpc.BridgeRpc.Login2FA:output_type -> google.protobuf.Empty - 58, // 140: bridgerpc.BridgeRpc.Login2Passwords:output_type -> google.protobuf.Empty - 58, // 141: bridgerpc.BridgeRpc.LoginAbort:output_type -> google.protobuf.Empty - 58, // 142: bridgerpc.BridgeRpc.CheckUpdate:output_type -> google.protobuf.Empty - 58, // 143: bridgerpc.BridgeRpc.InstallUpdate:output_type -> google.protobuf.Empty - 58, // 144: bridgerpc.BridgeRpc.SetIsAutomaticUpdateOn:output_type -> google.protobuf.Empty - 59, // 145: bridgerpc.BridgeRpc.IsAutomaticUpdateOn:output_type -> google.protobuf.BoolValue - 58, // 146: bridgerpc.BridgeRpc.SetIsCacheOnDiskEnabled:output_type -> google.protobuf.Empty - 59, // 147: bridgerpc.BridgeRpc.IsCacheOnDiskEnabled:output_type -> google.protobuf.BoolValue - 58, // 148: bridgerpc.BridgeRpc.SetDiskCachePath:output_type -> google.protobuf.Empty - 60, // 149: bridgerpc.BridgeRpc.DiskCachePath:output_type -> google.protobuf.StringValue - 58, // 150: bridgerpc.BridgeRpc.ChangeLocalCache:output_type -> google.protobuf.Empty - 58, // 151: bridgerpc.BridgeRpc.SetIsDoHEnabled:output_type -> google.protobuf.Empty - 59, // 152: bridgerpc.BridgeRpc.IsDoHEnabled:output_type -> google.protobuf.BoolValue - 58, // 153: bridgerpc.BridgeRpc.SetUseSslForSmtp:output_type -> google.protobuf.Empty - 59, // 154: bridgerpc.BridgeRpc.UseSslForSmtp:output_type -> google.protobuf.BoolValue - 60, // 155: bridgerpc.BridgeRpc.Hostname:output_type -> google.protobuf.StringValue - 58, // 156: bridgerpc.BridgeRpc.SetImapPort:output_type -> google.protobuf.Empty - 61, // 157: bridgerpc.BridgeRpc.ImapPort:output_type -> google.protobuf.Int32Value - 58, // 158: bridgerpc.BridgeRpc.SetSmtpPort:output_type -> google.protobuf.Empty - 61, // 159: bridgerpc.BridgeRpc.SmtpPort:output_type -> google.protobuf.Int32Value - 58, // 160: bridgerpc.BridgeRpc.ChangePorts:output_type -> google.protobuf.Empty - 59, // 161: bridgerpc.BridgeRpc.IsPortFree:output_type -> google.protobuf.BoolValue - 10, // 162: bridgerpc.BridgeRpc.AvailableKeychains:output_type -> bridgerpc.AvailableKeychainsResponse - 58, // 163: bridgerpc.BridgeRpc.SetCurrentKeychain:output_type -> google.protobuf.Empty - 60, // 164: bridgerpc.BridgeRpc.CurrentKeychain:output_type -> google.protobuf.StringValue - 13, // 165: bridgerpc.BridgeRpc.GetUserList:output_type -> bridgerpc.UserListResponse - 11, // 166: bridgerpc.BridgeRpc.GetUser:output_type -> bridgerpc.User - 58, // 167: bridgerpc.BridgeRpc.SetUserSplitMode:output_type -> google.protobuf.Empty - 58, // 168: bridgerpc.BridgeRpc.LogoutUser:output_type -> google.protobuf.Empty - 58, // 169: bridgerpc.BridgeRpc.RemoveUser:output_type -> google.protobuf.Empty - 58, // 170: bridgerpc.BridgeRpc.ConfigureUserAppleMail:output_type -> google.protobuf.Empty - 15, // 171: bridgerpc.BridgeRpc.GetEvents:output_type -> bridgerpc.StreamEvent - 110, // [110:172] is the sub-list for method output_type - 48, // [48:110] is the sub-list for method input_type - 48, // [48:48] is the sub-list for extension type_name - 48, // [48:48] is the sub-list for extension extendee - 0, // [0:48] is the sub-list for field type_name +var file_bridge_proto_depIdxs = []int32{ + 10, // 0: grpc.UserListResponse.users:type_name -> grpc.User + 15, // 1: grpc.StreamEvent.app:type_name -> grpc.AppEvent + 23, // 2: grpc.StreamEvent.login:type_name -> grpc.LoginEvent + 28, // 3: grpc.StreamEvent.update:type_name -> grpc.UpdateEvent + 36, // 4: grpc.StreamEvent.cache:type_name -> grpc.CacheEvent + 42, // 5: grpc.StreamEvent.mailSettings:type_name -> grpc.MailSettingsEvent + 46, // 6: grpc.StreamEvent.keychain:type_name -> grpc.KeychainEvent + 50, // 7: grpc.StreamEvent.mail:type_name -> grpc.MailEvent + 55, // 8: grpc.StreamEvent.user:type_name -> grpc.UserEvent + 16, // 9: grpc.AppEvent.internetStatus:type_name -> grpc.InternetStatusEvent + 17, // 10: grpc.AppEvent.toggleAutostartFinished:type_name -> grpc.ToggleAutostartFinishedEvent + 18, // 11: grpc.AppEvent.resetFinished:type_name -> grpc.ResetFinishedEvent + 19, // 12: grpc.AppEvent.reportBugFinished:type_name -> grpc.ReportBugFinishedEvent + 20, // 13: grpc.AppEvent.reportBugSuccess:type_name -> grpc.ReportBugSuccessEvent + 21, // 14: grpc.AppEvent.reportBugError:type_name -> grpc.ReportBugErrorEvent + 22, // 15: grpc.AppEvent.showMainWindow:type_name -> grpc.ShowMainWindowEvent + 24, // 16: grpc.LoginEvent.error:type_name -> grpc.LoginErrorEvent + 25, // 17: grpc.LoginEvent.tfaRequested:type_name -> grpc.LoginTfaRequestedEvent + 26, // 18: grpc.LoginEvent.twoPasswordRequested:type_name -> grpc.LoginTwoPasswordsRequestedEvent + 27, // 19: grpc.LoginEvent.finished:type_name -> grpc.LoginFinishedEvent + 27, // 20: grpc.LoginEvent.alreadyLoggedIn:type_name -> grpc.LoginFinishedEvent + 0, // 21: grpc.LoginErrorEvent.type:type_name -> grpc.LoginErrorType + 29, // 22: grpc.UpdateEvent.error:type_name -> grpc.UpdateErrorEvent + 30, // 23: grpc.UpdateEvent.manualReady:type_name -> grpc.UpdateManualReadyEvent + 31, // 24: grpc.UpdateEvent.manualRestartNeeded:type_name -> grpc.UpdateManualRestartNeededEvent + 32, // 25: grpc.UpdateEvent.force:type_name -> grpc.UpdateForceEvent + 33, // 26: grpc.UpdateEvent.silentRestartNeeded:type_name -> grpc.UpdateSilentRestartNeeded + 34, // 27: grpc.UpdateEvent.isLatestVersion:type_name -> grpc.UpdateIsLatestVersion + 35, // 28: grpc.UpdateEvent.checkFinished:type_name -> grpc.UpdateCheckFinished + 1, // 29: grpc.UpdateErrorEvent.type:type_name -> grpc.UpdateErrorType + 37, // 30: grpc.CacheEvent.error:type_name -> grpc.CacheErrorEvent + 38, // 31: grpc.CacheEvent.locationChangedSuccess:type_name -> grpc.CacheLocationChangeSuccessEvent + 39, // 32: grpc.CacheEvent.changeLocalCacheFinished:type_name -> grpc.ChangeLocalCacheFinishedEvent + 40, // 33: grpc.CacheEvent.isCacheOnDiskEnabledChanged:type_name -> grpc.IsCacheOnDiskEnabledChanged + 41, // 34: grpc.CacheEvent.diskCachePathChanged:type_name -> grpc.DiskCachePathChanged + 2, // 35: grpc.CacheErrorEvent.type:type_name -> grpc.CacheErrorType + 43, // 36: grpc.MailSettingsEvent.error:type_name -> grpc.MailSettingsErrorEvent + 44, // 37: grpc.MailSettingsEvent.useSslForSmtpFinished:type_name -> grpc.UseSslForSmtpFinishedEvent + 45, // 38: grpc.MailSettingsEvent.changePortsFinished:type_name -> grpc.ChangePortsFinishedEvent + 3, // 39: grpc.MailSettingsErrorEvent.type:type_name -> grpc.MailSettingsErrorType + 47, // 40: grpc.KeychainEvent.changeKeychainFinished:type_name -> grpc.ChangeKeychainFinishedEvent + 48, // 41: grpc.KeychainEvent.hasNoKeychain:type_name -> grpc.HasNoKeychainEvent + 49, // 42: grpc.KeychainEvent.rebuildKeychain:type_name -> grpc.RebuildKeychainEvent + 51, // 43: grpc.MailEvent.noActiveKeyForRecipientEvent:type_name -> grpc.NoActiveKeyForRecipientEvent + 52, // 44: grpc.MailEvent.addressChanged:type_name -> grpc.AddressChangedEvent + 53, // 45: grpc.MailEvent.addressChangedLogout:type_name -> grpc.AddressChangedLogoutEvent + 54, // 46: grpc.MailEvent.apiCertIssue:type_name -> grpc.ApiCertIssueEvent + 56, // 47: grpc.UserEvent.toggleSplitModeFinished:type_name -> grpc.ToggleSplitModeFinishedEvent + 57, // 48: grpc.UserEvent.userDisconnected:type_name -> grpc.UserDisconnectedEvent + 58, // 49: grpc.UserEvent.userChanged:type_name -> grpc.UserChangedEvent + 59, // 50: grpc.Bridge.GuiReady:input_type -> google.protobuf.Empty + 59, // 51: grpc.Bridge.Quit:input_type -> google.protobuf.Empty + 59, // 52: grpc.Bridge.Restart:input_type -> google.protobuf.Empty + 59, // 53: grpc.Bridge.ShowOnStartup:input_type -> google.protobuf.Empty + 59, // 54: grpc.Bridge.ShowSplashScreen:input_type -> google.protobuf.Empty + 59, // 55: grpc.Bridge.IsFirstGuiStart:input_type -> google.protobuf.Empty + 60, // 56: grpc.Bridge.SetIsAutostartOn:input_type -> google.protobuf.BoolValue + 59, // 57: grpc.Bridge.IsAutostartOn:input_type -> google.protobuf.Empty + 60, // 58: grpc.Bridge.SetIsBetaEnabled:input_type -> google.protobuf.BoolValue + 59, // 59: grpc.Bridge.IsBetaEnabled:input_type -> google.protobuf.Empty + 59, // 60: grpc.Bridge.GoOs:input_type -> google.protobuf.Empty + 59, // 61: grpc.Bridge.TriggerReset:input_type -> google.protobuf.Empty + 59, // 62: grpc.Bridge.Version:input_type -> google.protobuf.Empty + 59, // 63: grpc.Bridge.LogsPath:input_type -> google.protobuf.Empty + 59, // 64: grpc.Bridge.LicensePath:input_type -> google.protobuf.Empty + 59, // 65: grpc.Bridge.DependencyLicensesLink:input_type -> google.protobuf.Empty + 61, // 66: grpc.Bridge.SetColorSchemeName:input_type -> google.protobuf.StringValue + 59, // 67: grpc.Bridge.ColorSchemeName:input_type -> google.protobuf.Empty + 59, // 68: grpc.Bridge.CurrentEmailClient:input_type -> google.protobuf.Empty + 4, // 69: grpc.Bridge.ReportBug:input_type -> grpc.ReportBugRequest + 5, // 70: grpc.Bridge.Login:input_type -> grpc.LoginRequest + 5, // 71: grpc.Bridge.Login2FA:input_type -> grpc.LoginRequest + 5, // 72: grpc.Bridge.Login2Passwords:input_type -> grpc.LoginRequest + 6, // 73: grpc.Bridge.LoginAbort:input_type -> grpc.LoginAbortRequest + 59, // 74: grpc.Bridge.CheckUpdate:input_type -> google.protobuf.Empty + 59, // 75: grpc.Bridge.InstallUpdate:input_type -> google.protobuf.Empty + 60, // 76: grpc.Bridge.SetIsAutomaticUpdateOn:input_type -> google.protobuf.BoolValue + 59, // 77: grpc.Bridge.IsAutomaticUpdateOn:input_type -> google.protobuf.Empty + 59, // 78: grpc.Bridge.IsCacheOnDiskEnabled:input_type -> google.protobuf.Empty + 59, // 79: grpc.Bridge.DiskCachePath:input_type -> google.protobuf.Empty + 7, // 80: grpc.Bridge.ChangeLocalCache:input_type -> grpc.ChangeLocalCacheRequest + 60, // 81: grpc.Bridge.SetIsDoHEnabled:input_type -> google.protobuf.BoolValue + 59, // 82: grpc.Bridge.IsDoHEnabled:input_type -> google.protobuf.Empty + 60, // 83: grpc.Bridge.SetUseSslForSmtp:input_type -> google.protobuf.BoolValue + 59, // 84: grpc.Bridge.UseSslForSmtp:input_type -> google.protobuf.Empty + 59, // 85: grpc.Bridge.Hostname:input_type -> google.protobuf.Empty + 59, // 86: grpc.Bridge.ImapPort:input_type -> google.protobuf.Empty + 59, // 87: grpc.Bridge.SmtpPort:input_type -> google.protobuf.Empty + 8, // 88: grpc.Bridge.ChangePorts:input_type -> grpc.ChangePortsRequest + 62, // 89: grpc.Bridge.IsPortFree:input_type -> google.protobuf.Int32Value + 59, // 90: grpc.Bridge.AvailableKeychains:input_type -> google.protobuf.Empty + 61, // 91: grpc.Bridge.SetCurrentKeychain:input_type -> google.protobuf.StringValue + 59, // 92: grpc.Bridge.CurrentKeychain:input_type -> google.protobuf.Empty + 59, // 93: grpc.Bridge.GetUserList:input_type -> google.protobuf.Empty + 61, // 94: grpc.Bridge.GetUser:input_type -> google.protobuf.StringValue + 11, // 95: grpc.Bridge.SetUserSplitMode:input_type -> grpc.UserSplitModeRequest + 61, // 96: grpc.Bridge.LogoutUser:input_type -> google.protobuf.StringValue + 61, // 97: grpc.Bridge.RemoveUser:input_type -> google.protobuf.StringValue + 13, // 98: grpc.Bridge.ConfigureUserAppleMail:input_type -> grpc.ConfigureAppleMailRequest + 59, // 99: grpc.Bridge.StartEventStream:input_type -> google.protobuf.Empty + 59, // 100: grpc.Bridge.StopEventStream:input_type -> google.protobuf.Empty + 59, // 101: grpc.Bridge.GuiReady:output_type -> google.protobuf.Empty + 59, // 102: grpc.Bridge.Quit:output_type -> google.protobuf.Empty + 59, // 103: grpc.Bridge.Restart:output_type -> google.protobuf.Empty + 60, // 104: grpc.Bridge.ShowOnStartup:output_type -> google.protobuf.BoolValue + 60, // 105: grpc.Bridge.ShowSplashScreen:output_type -> google.protobuf.BoolValue + 60, // 106: grpc.Bridge.IsFirstGuiStart:output_type -> google.protobuf.BoolValue + 59, // 107: grpc.Bridge.SetIsAutostartOn:output_type -> google.protobuf.Empty + 60, // 108: grpc.Bridge.IsAutostartOn:output_type -> google.protobuf.BoolValue + 59, // 109: grpc.Bridge.SetIsBetaEnabled:output_type -> google.protobuf.Empty + 60, // 110: grpc.Bridge.IsBetaEnabled:output_type -> google.protobuf.BoolValue + 61, // 111: grpc.Bridge.GoOs:output_type -> google.protobuf.StringValue + 59, // 112: grpc.Bridge.TriggerReset:output_type -> google.protobuf.Empty + 61, // 113: grpc.Bridge.Version:output_type -> google.protobuf.StringValue + 61, // 114: grpc.Bridge.LogsPath:output_type -> google.protobuf.StringValue + 61, // 115: grpc.Bridge.LicensePath:output_type -> google.protobuf.StringValue + 61, // 116: grpc.Bridge.DependencyLicensesLink:output_type -> google.protobuf.StringValue + 59, // 117: grpc.Bridge.SetColorSchemeName:output_type -> google.protobuf.Empty + 61, // 118: grpc.Bridge.ColorSchemeName:output_type -> google.protobuf.StringValue + 61, // 119: grpc.Bridge.CurrentEmailClient:output_type -> google.protobuf.StringValue + 59, // 120: grpc.Bridge.ReportBug:output_type -> google.protobuf.Empty + 59, // 121: grpc.Bridge.Login:output_type -> google.protobuf.Empty + 59, // 122: grpc.Bridge.Login2FA:output_type -> google.protobuf.Empty + 59, // 123: grpc.Bridge.Login2Passwords:output_type -> google.protobuf.Empty + 59, // 124: grpc.Bridge.LoginAbort:output_type -> google.protobuf.Empty + 59, // 125: grpc.Bridge.CheckUpdate:output_type -> google.protobuf.Empty + 59, // 126: grpc.Bridge.InstallUpdate:output_type -> google.protobuf.Empty + 59, // 127: grpc.Bridge.SetIsAutomaticUpdateOn:output_type -> google.protobuf.Empty + 60, // 128: grpc.Bridge.IsAutomaticUpdateOn:output_type -> google.protobuf.BoolValue + 60, // 129: grpc.Bridge.IsCacheOnDiskEnabled:output_type -> google.protobuf.BoolValue + 61, // 130: grpc.Bridge.DiskCachePath:output_type -> google.protobuf.StringValue + 59, // 131: grpc.Bridge.ChangeLocalCache:output_type -> google.protobuf.Empty + 59, // 132: grpc.Bridge.SetIsDoHEnabled:output_type -> google.protobuf.Empty + 60, // 133: grpc.Bridge.IsDoHEnabled:output_type -> google.protobuf.BoolValue + 59, // 134: grpc.Bridge.SetUseSslForSmtp:output_type -> google.protobuf.Empty + 60, // 135: grpc.Bridge.UseSslForSmtp:output_type -> google.protobuf.BoolValue + 61, // 136: grpc.Bridge.Hostname:output_type -> google.protobuf.StringValue + 62, // 137: grpc.Bridge.ImapPort:output_type -> google.protobuf.Int32Value + 62, // 138: grpc.Bridge.SmtpPort:output_type -> google.protobuf.Int32Value + 59, // 139: grpc.Bridge.ChangePorts:output_type -> google.protobuf.Empty + 60, // 140: grpc.Bridge.IsPortFree:output_type -> google.protobuf.BoolValue + 9, // 141: grpc.Bridge.AvailableKeychains:output_type -> grpc.AvailableKeychainsResponse + 59, // 142: grpc.Bridge.SetCurrentKeychain:output_type -> google.protobuf.Empty + 61, // 143: grpc.Bridge.CurrentKeychain:output_type -> google.protobuf.StringValue + 12, // 144: grpc.Bridge.GetUserList:output_type -> grpc.UserListResponse + 10, // 145: grpc.Bridge.GetUser:output_type -> grpc.User + 59, // 146: grpc.Bridge.SetUserSplitMode:output_type -> google.protobuf.Empty + 59, // 147: grpc.Bridge.LogoutUser:output_type -> google.protobuf.Empty + 59, // 148: grpc.Bridge.RemoveUser:output_type -> google.protobuf.Empty + 59, // 149: grpc.Bridge.ConfigureUserAppleMail:output_type -> google.protobuf.Empty + 14, // 150: grpc.Bridge.StartEventStream:output_type -> grpc.StreamEvent + 59, // 151: grpc.Bridge.StopEventStream:output_type -> google.protobuf.Empty + 101, // [101:152] is the sub-list for method output_type + 50, // [50:101] is the sub-list for method input_type + 50, // [50:50] is the sub-list for extension type_name + 50, // [50:50] is the sub-list for extension extendee + 0, // [0:50] is the sub-list for field type_name } -func init() { file_bridge_rpc_proto_init() } -func file_bridge_rpc_proto_init() { - if File_bridge_rpc_proto != nil { +func init() { file_bridge_proto_init() } +func file_bridge_proto_init() { + if File_bridge_proto != nil { return } if !protoimpl.UnsafeEnabled { - file_bridge_rpc_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PointResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_bridge_rpc_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReportBugRequest); i { case 0: return &v.state @@ -4397,7 +4394,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*LoginRequest); i { case 0: return &v.state @@ -4409,7 +4406,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*LoginAbortRequest); i { case 0: return &v.state @@ -4421,7 +4418,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ChangeLocalCacheRequest); i { case 0: return &v.state @@ -4433,7 +4430,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ChangePortsRequest); i { case 0: return &v.state @@ -4445,7 +4442,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*AvailableKeychainsResponse); i { case 0: return &v.state @@ -4457,7 +4454,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*User); i { case 0: return &v.state @@ -4469,7 +4466,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UserSplitModeRequest); i { case 0: return &v.state @@ -4481,7 +4478,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UserListResponse); i { case 0: return &v.state @@ -4493,7 +4490,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ConfigureAppleMailRequest); i { case 0: return &v.state @@ -4505,7 +4502,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*StreamEvent); i { case 0: return &v.state @@ -4517,7 +4514,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*AppEvent); i { case 0: return &v.state @@ -4529,7 +4526,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*InternetStatusEvent); i { case 0: return &v.state @@ -4541,8 +4538,8 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AutostartFinishedEvent); i { + file_bridge_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ToggleAutostartFinishedEvent); i { case 0: return &v.state case 1: @@ -4553,7 +4550,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ResetFinishedEvent); i { case 0: return &v.state @@ -4565,7 +4562,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReportBugFinishedEvent); i { case 0: return &v.state @@ -4577,7 +4574,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReportBugSuccessEvent); i { case 0: return &v.state @@ -4589,7 +4586,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReportBugErrorEvent); i { case 0: return &v.state @@ -4601,7 +4598,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ShowMainWindowEvent); i { case 0: return &v.state @@ -4613,7 +4610,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*LoginEvent); i { case 0: return &v.state @@ -4625,7 +4622,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*LoginErrorEvent); i { case 0: return &v.state @@ -4637,7 +4634,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*LoginTfaRequestedEvent); i { case 0: return &v.state @@ -4649,7 +4646,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*LoginTwoPasswordsRequestedEvent); i { case 0: return &v.state @@ -4661,7 +4658,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*LoginFinishedEvent); i { case 0: return &v.state @@ -4673,7 +4670,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UpdateEvent); i { case 0: return &v.state @@ -4685,7 +4682,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UpdateErrorEvent); i { case 0: return &v.state @@ -4697,7 +4694,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UpdateManualReadyEvent); i { case 0: return &v.state @@ -4709,7 +4706,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UpdateManualRestartNeededEvent); i { case 0: return &v.state @@ -4721,7 +4718,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UpdateForceEvent); i { case 0: return &v.state @@ -4733,7 +4730,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UpdateSilentRestartNeeded); i { case 0: return &v.state @@ -4745,7 +4742,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UpdateIsLatestVersion); i { case 0: return &v.state @@ -4757,7 +4754,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UpdateCheckFinished); i { case 0: return &v.state @@ -4769,7 +4766,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CacheEvent); i { case 0: return &v.state @@ -4781,7 +4778,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CacheErrorEvent); i { case 0: return &v.state @@ -4793,7 +4790,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CacheLocationChangeSuccessEvent); i { case 0: return &v.state @@ -4805,7 +4802,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ChangeLocalCacheFinishedEvent); i { case 0: return &v.state @@ -4817,7 +4814,31 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*IsCacheOnDiskEnabledChanged); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_bridge_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DiskCachePathChanged); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_bridge_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*MailSettingsEvent); i { case 0: return &v.state @@ -4829,7 +4850,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*MailSettingsErrorEvent); i { case 0: return &v.state @@ -4841,7 +4862,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UseSslForSmtpFinishedEvent); i { case 0: return &v.state @@ -4853,7 +4874,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ChangePortsFinishedEvent); i { case 0: return &v.state @@ -4865,7 +4886,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*KeychainEvent); i { case 0: return &v.state @@ -4877,7 +4898,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ChangeKeychainFinishedEvent); i { case 0: return &v.state @@ -4889,7 +4910,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*HasNoKeychainEvent); i { case 0: return &v.state @@ -4901,7 +4922,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RebuildKeychainEvent); i { case 0: return &v.state @@ -4913,7 +4934,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*MailEvent); i { case 0: return &v.state @@ -4925,7 +4946,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*NoActiveKeyForRecipientEvent); i { case 0: return &v.state @@ -4937,7 +4958,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*AddressChangedEvent); i { case 0: return &v.state @@ -4949,7 +4970,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*AddressChangedLogoutEvent); i { case 0: return &v.state @@ -4961,7 +4982,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ApiCertIssueEvent); i { case 0: return &v.state @@ -4973,7 +4994,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[51].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UserEvent); i { case 0: return &v.state @@ -4985,7 +5006,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[51].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[52].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ToggleSplitModeFinishedEvent); i { case 0: return &v.state @@ -4997,7 +5018,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[52].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[53].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UserDisconnectedEvent); i { case 0: return &v.state @@ -5009,7 +5030,7 @@ func file_bridge_rpc_proto_init() { return nil } } - file_bridge_rpc_proto_msgTypes[53].Exporter = func(v interface{}, i int) interface{} { + file_bridge_proto_msgTypes[54].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UserChangedEvent); i { case 0: return &v.state @@ -5022,7 +5043,7 @@ func file_bridge_rpc_proto_init() { } } } - file_bridge_rpc_proto_msgTypes[11].OneofWrappers = []interface{}{ + file_bridge_proto_msgTypes[10].OneofWrappers = []interface{}{ (*StreamEvent_App)(nil), (*StreamEvent_Login)(nil), (*StreamEvent_Update)(nil), @@ -5032,22 +5053,23 @@ func file_bridge_rpc_proto_init() { (*StreamEvent_Mail)(nil), (*StreamEvent_User)(nil), } - file_bridge_rpc_proto_msgTypes[12].OneofWrappers = []interface{}{ + file_bridge_proto_msgTypes[11].OneofWrappers = []interface{}{ (*AppEvent_InternetStatus)(nil), - (*AppEvent_AutostartFinished)(nil), + (*AppEvent_ToggleAutostartFinished)(nil), (*AppEvent_ResetFinished)(nil), (*AppEvent_ReportBugFinished)(nil), (*AppEvent_ReportBugSuccess)(nil), (*AppEvent_ReportBugError)(nil), (*AppEvent_ShowMainWindow)(nil), } - file_bridge_rpc_proto_msgTypes[20].OneofWrappers = []interface{}{ + file_bridge_proto_msgTypes[19].OneofWrappers = []interface{}{ (*LoginEvent_Error)(nil), (*LoginEvent_TfaRequested)(nil), (*LoginEvent_TwoPasswordRequested)(nil), (*LoginEvent_Finished)(nil), + (*LoginEvent_AlreadyLoggedIn)(nil), } - file_bridge_rpc_proto_msgTypes[25].OneofWrappers = []interface{}{ + file_bridge_proto_msgTypes[24].OneofWrappers = []interface{}{ (*UpdateEvent_Error)(nil), (*UpdateEvent_ManualReady)(nil), (*UpdateEvent_ManualRestartNeeded)(nil), @@ -5056,28 +5078,30 @@ func file_bridge_rpc_proto_init() { (*UpdateEvent_IsLatestVersion)(nil), (*UpdateEvent_CheckFinished)(nil), } - file_bridge_rpc_proto_msgTypes[33].OneofWrappers = []interface{}{ + file_bridge_proto_msgTypes[32].OneofWrappers = []interface{}{ (*CacheEvent_Error)(nil), (*CacheEvent_LocationChangedSuccess)(nil), (*CacheEvent_ChangeLocalCacheFinished)(nil), + (*CacheEvent_IsCacheOnDiskEnabledChanged)(nil), + (*CacheEvent_DiskCachePathChanged)(nil), } - file_bridge_rpc_proto_msgTypes[37].OneofWrappers = []interface{}{ + file_bridge_proto_msgTypes[38].OneofWrappers = []interface{}{ (*MailSettingsEvent_Error)(nil), (*MailSettingsEvent_UseSslForSmtpFinished)(nil), (*MailSettingsEvent_ChangePortsFinished)(nil), } - file_bridge_rpc_proto_msgTypes[41].OneofWrappers = []interface{}{ + file_bridge_proto_msgTypes[42].OneofWrappers = []interface{}{ (*KeychainEvent_ChangeKeychainFinished)(nil), (*KeychainEvent_HasNoKeychain)(nil), (*KeychainEvent_RebuildKeychain)(nil), } - file_bridge_rpc_proto_msgTypes[45].OneofWrappers = []interface{}{ + file_bridge_proto_msgTypes[46].OneofWrappers = []interface{}{ (*MailEvent_NoActiveKeyForRecipientEvent)(nil), (*MailEvent_AddressChanged)(nil), (*MailEvent_AddressChangedLogout)(nil), (*MailEvent_ApiCertIssue)(nil), } - file_bridge_rpc_proto_msgTypes[50].OneofWrappers = []interface{}{ + file_bridge_proto_msgTypes[51].OneofWrappers = []interface{}{ (*UserEvent_ToggleSplitModeFinished)(nil), (*UserEvent_UserDisconnected)(nil), (*UserEvent_UserChanged)(nil), @@ -5086,19 +5110,19 @@ func file_bridge_rpc_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_bridge_rpc_proto_rawDesc, + RawDescriptor: file_bridge_proto_rawDesc, NumEnums: 4, - NumMessages: 54, + NumMessages: 55, NumExtensions: 0, NumServices: 1, }, - GoTypes: file_bridge_rpc_proto_goTypes, - DependencyIndexes: file_bridge_rpc_proto_depIdxs, - EnumInfos: file_bridge_rpc_proto_enumTypes, - MessageInfos: file_bridge_rpc_proto_msgTypes, + GoTypes: file_bridge_proto_goTypes, + DependencyIndexes: file_bridge_proto_depIdxs, + EnumInfos: file_bridge_proto_enumTypes, + MessageInfos: file_bridge_proto_msgTypes, }.Build() - File_bridge_rpc_proto = out.File - file_bridge_rpc_proto_rawDesc = nil - file_bridge_rpc_proto_goTypes = nil - file_bridge_rpc_proto_depIdxs = nil + File_bridge_proto = out.File + file_bridge_proto_rawDesc = nil + file_bridge_proto_goTypes = nil + file_bridge_proto_depIdxs = nil } diff --git a/internal/rpc/bridge_rpc.proto b/internal/frontend/grpc/bridge.proto similarity index 86% rename from internal/rpc/bridge_rpc.proto rename to internal/frontend/grpc/bridge.proto index 70a7ae36..bc346ac2 100644 --- a/internal/rpc/bridge_rpc.proto +++ b/internal/frontend/grpc/bridge.proto @@ -20,27 +20,21 @@ syntax = "proto3"; import "google/protobuf/empty.proto"; import "google/protobuf/wrappers.proto"; -option go_package = "github.com/ProtonMail/proton-bridge/internal/rpc"; +option go_package = "github.com/ProtonMail/proton-bridge/internal/grpc"; -package bridgerpc; // ignored by Go, used as namespace name in C++. +package grpc; // ignored by Go, used as namespace name in C++. //********************************************************************************************************************** // Service Declaration //********************************************************************************************************************** -service BridgeRpc { +service Bridge { // App related calls - rpc GetCursorPos (google.protobuf.Empty) returns (PointResponse); // May be unnecessary rpc GuiReady (google.protobuf.Empty) returns (google.protobuf.Empty); rpc Quit (google.protobuf.Empty) returns (google.protobuf.Empty); rpc Restart (google.protobuf.Empty) returns (google.protobuf.Empty); - rpc SetShowOnStartup(google.protobuf.BoolValue) returns (google.protobuf.Empty); rpc ShowOnStartup(google.protobuf.Empty) returns (google.protobuf.BoolValue); - rpc SetShowSplashScreen(google.protobuf.BoolValue) returns (google.protobuf.Empty); rpc ShowSplashScreen(google.protobuf.Empty) returns (google.protobuf.BoolValue); - rpc SetDockIconVisible(google.protobuf.BoolValue) returns (google.protobuf.Empty); - rpc DockIconVisible(google.protobuf.Empty) returns (google.protobuf.BoolValue); - rpc SetIsFirstGuiStart(google.protobuf.BoolValue) returns (google.protobuf.Empty); rpc IsFirstGuiStart(google.protobuf.Empty) returns (google.protobuf.BoolValue); rpc SetIsAutostartOn(google.protobuf.BoolValue) returns (google.protobuf.Empty); rpc IsAutostartOn(google.protobuf.Empty) returns (google.protobuf.BoolValue); @@ -49,13 +43,13 @@ service BridgeRpc { rpc GoOs(google.protobuf.Empty) returns (google.protobuf.StringValue); rpc TriggerReset(google.protobuf.Empty) returns (google.protobuf.Empty); rpc Version(google.protobuf.Empty) returns (google.protobuf.StringValue); - rpc LogPath(google.protobuf.Empty) returns (google.protobuf.StringValue); + rpc LogsPath(google.protobuf.Empty) returns (google.protobuf.StringValue); rpc LicensePath(google.protobuf.Empty) returns (google.protobuf.StringValue); - rpc ReleaseNotesLink(google.protobuf.Empty) returns (google.protobuf.StringValue); - rpc LandingPageLink(google.protobuf.Empty) returns (google.protobuf.StringValue); +// rpc ReleaseNotesLink(google.protobuf.Empty) returns (google.protobuf.StringValue); // TODO GODT-1670 Apparently cannot be polled for now, will be sent as update. + rpc DependencyLicensesLink(google.protobuf.Empty) returns (google.protobuf.StringValue); +// rpc LandingPageLink(google.protobuf.Empty) returns (google.protobuf.StringValue); // TODO GODT-1670 Apparently cannot be polled for now, will be sent as update. rpc SetColorSchemeName(google.protobuf.StringValue) returns (google.protobuf.Empty); - rpc ColorSchemeName(google.protobuf.Empty) returns (google.protobuf.StringValue); - rpc SetCurrentEmailClient(google.protobuf.StringValue) returns (google.protobuf.Empty); + rpc ColorSchemeName(google.protobuf.Empty) returns (google.protobuf.StringValue); // TODO Color scheme should probably entirely be managed by the client. rpc CurrentEmailClient(google.protobuf.Empty) returns (google.protobuf.StringValue); rpc ReportBug(ReportBugRequest) returns (google.protobuf.Empty); @@ -72,9 +66,7 @@ service BridgeRpc { rpc IsAutomaticUpdateOn(google.protobuf.Empty) returns (google.protobuf.BoolValue); // cache - rpc SetIsCacheOnDiskEnabled (google.protobuf.BoolValue) returns (google.protobuf.Empty); rpc IsCacheOnDiskEnabled (google.protobuf.Empty) returns (google.protobuf.BoolValue); - rpc SetDiskCachePath (google.protobuf.StringValue) returns (google.protobuf.Empty); rpc DiskCachePath(google.protobuf.Empty) returns (google.protobuf.StringValue); rpc ChangeLocalCache(ChangeLocalCacheRequest) returns (google.protobuf.Empty); @@ -84,9 +76,7 @@ service BridgeRpc { rpc SetUseSslForSmtp(google.protobuf.BoolValue) returns (google.protobuf.Empty); rpc UseSslForSmtp(google.protobuf.Empty) returns (google.protobuf.BoolValue); rpc Hostname(google.protobuf.Empty) returns (google.protobuf.StringValue); - rpc SetImapPort(google.protobuf.Int32Value) returns (google.protobuf.Empty); rpc ImapPort(google.protobuf.Empty) returns (google.protobuf.Int32Value); - rpc SetSmtpPort(google.protobuf.Int32Value) returns (google.protobuf.Empty); rpc SmtpPort(google.protobuf.Empty) returns (google.protobuf.Int32Value); rpc ChangePorts(ChangePortsRequest) returns (google.protobuf.Empty); rpc IsPortFree(google.protobuf.Int32Value) returns (google.protobuf.BoolValue); @@ -98,28 +88,21 @@ service BridgeRpc { // User & user list rpc GetUserList(google.protobuf.Empty) returns (UserListResponse); - rpc GetUser(google.protobuf.Empty) returns (User); + rpc GetUser(google.protobuf.StringValue) returns (User); rpc SetUserSplitMode(UserSplitModeRequest) returns (google.protobuf.Empty); rpc LogoutUser(google.protobuf.StringValue) returns (google.protobuf.Empty); rpc RemoveUser(google.protobuf.StringValue) returns (google.protobuf.Empty); rpc ConfigureUserAppleMail(ConfigureAppleMailRequest) returns (google.protobuf.Empty); // Server -> Client event stream - rpc GetEvents(google.protobuf.Empty) returns (stream StreamEvent); + rpc StartEventStream(google.protobuf.Empty) returns (stream StreamEvent); // Keep streaming until StopEventStream is called. + rpc StopEventStream(google.protobuf.Empty) returns (google.protobuf.Empty); } //********************************************************************************************************************** // RPC calls requests and replies messages //********************************************************************************************************************** -//********************************************************** -// GUI related messages -//********************************************************** -message PointResponse { - int32 x = 1; - int32 y = 2; -}; - message ReportBugRequest { string description = 1; string address = 2; @@ -214,7 +197,7 @@ message StreamEvent { message AppEvent { oneof event { InternetStatusEvent internetStatus = 1; - AutostartFinishedEvent autostartFinished = 2; + ToggleAutostartFinishedEvent toggleAutostartFinished = 2; ResetFinishedEvent resetFinished = 3; ReportBugFinishedEvent reportBugFinished = 4; ReportBugSuccessEvent reportBugSuccess = 5; @@ -227,7 +210,7 @@ message InternetStatusEvent { bool connected = 1; } -message AutostartFinishedEvent {} +message ToggleAutostartFinishedEvent {} message ResetFinishedEvent {} message ReportBugFinishedEvent {} message ReportBugSuccessEvent {} @@ -243,6 +226,7 @@ message LoginEvent { LoginTfaRequestedEvent tfaRequested = 2; LoginTwoPasswordsRequestedEvent twoPasswordRequested = 3; LoginFinishedEvent finished = 4; + LoginFinishedEvent alreadyLoggedIn = 5; } } @@ -268,7 +252,7 @@ message LoginTfaRequestedEvent { message LoginTwoPasswordsRequestedEvent {} message LoginFinishedEvent { - bool wasAlreadyLoggedIn = 1; + string userID = 1; } //********************************************************** @@ -320,6 +304,8 @@ message CacheEvent { CacheErrorEvent error = 1; CacheLocationChangeSuccessEvent locationChangedSuccess = 2; ChangeLocalCacheFinishedEvent changeLocalCacheFinished = 3; + IsCacheOnDiskEnabledChanged isCacheOnDiskEnabledChanged = 4; + DiskCachePathChanged diskCachePathChanged = 5; } } @@ -337,6 +323,16 @@ message CacheLocationChangeSuccessEvent {}; message ChangeLocalCacheFinishedEvent {}; + +message IsCacheOnDiskEnabledChanged { + bool enabled = 1; +} + +message DiskCachePathChanged { + string path = 1; +} + + //********************************************************** // Mail settings related events //********************************************************** @@ -393,11 +389,11 @@ message NoActiveKeyForRecipientEvent { } message AddressChangedEvent { - string address = 1; // TODO: user event ? + string address = 1; } message AddressChangedLogoutEvent { - string address = 1; // TODO: user event ? + string address = 1; } message ApiCertIssueEvent {} @@ -419,10 +415,10 @@ message ToggleSplitModeFinishedEvent { } message UserDisconnectedEvent { - string username = 1; // TODO: isn't it userID ? + string username = 1; } message UserChangedEvent { - User user = 1; + string userID = 1; } diff --git a/internal/frontend/grpc/bridge_grpc.pb.go b/internal/frontend/grpc/bridge_grpc.pb.go new file mode 100644 index 00000000..6a45454c --- /dev/null +++ b/internal/frontend/grpc/bridge_grpc.pb.go @@ -0,0 +1,1955 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.19.4 +// source: bridge.proto + +package grpc + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + emptypb "google.golang.org/protobuf/types/known/emptypb" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// BridgeClient is the client API for Bridge service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type BridgeClient interface { + // App related calls + GuiReady(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) + Quit(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) + Restart(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) + ShowOnStartup(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) + ShowSplashScreen(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) + IsFirstGuiStart(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) + SetIsAutostartOn(ctx context.Context, in *wrapperspb.BoolValue, opts ...grpc.CallOption) (*emptypb.Empty, error) + IsAutostartOn(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) + SetIsBetaEnabled(ctx context.Context, in *wrapperspb.BoolValue, opts ...grpc.CallOption) (*emptypb.Empty, error) + IsBetaEnabled(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) + GoOs(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) + TriggerReset(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) + Version(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) + LogsPath(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) + LicensePath(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) + // rpc ReleaseNotesLink(google.protobuf.Empty) returns (google.protobuf.StringValue); // TODO Apparently cannot be polled for now, will be sent as update. + DependencyLicensesLink(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) + // rpc LandingPageLink(google.protobuf.Empty) returns (google.protobuf.StringValue); // TODO Apparently cannot be polled for now, will be sent as update. + SetColorSchemeName(ctx context.Context, in *wrapperspb.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) + ColorSchemeName(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) + CurrentEmailClient(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) + ReportBug(ctx context.Context, in *ReportBugRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + // login + Login(ctx context.Context, in *LoginRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + Login2FA(ctx context.Context, in *LoginRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + Login2Passwords(ctx context.Context, in *LoginRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + LoginAbort(ctx context.Context, in *LoginAbortRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + // update + CheckUpdate(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) + InstallUpdate(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) + SetIsAutomaticUpdateOn(ctx context.Context, in *wrapperspb.BoolValue, opts ...grpc.CallOption) (*emptypb.Empty, error) + IsAutomaticUpdateOn(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) + // cache + IsCacheOnDiskEnabled(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) + DiskCachePath(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) + ChangeLocalCache(ctx context.Context, in *ChangeLocalCacheRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + // mail + SetIsDoHEnabled(ctx context.Context, in *wrapperspb.BoolValue, opts ...grpc.CallOption) (*emptypb.Empty, error) + IsDoHEnabled(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) + SetUseSslForSmtp(ctx context.Context, in *wrapperspb.BoolValue, opts ...grpc.CallOption) (*emptypb.Empty, error) + UseSslForSmtp(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) + Hostname(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) + ImapPort(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.Int32Value, error) + SmtpPort(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.Int32Value, error) + ChangePorts(ctx context.Context, in *ChangePortsRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + IsPortFree(ctx context.Context, in *wrapperspb.Int32Value, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) + // keychain + AvailableKeychains(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*AvailableKeychainsResponse, error) + SetCurrentKeychain(ctx context.Context, in *wrapperspb.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) + CurrentKeychain(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) + // User & user list + GetUserList(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*UserListResponse, error) + GetUser(ctx context.Context, in *wrapperspb.StringValue, opts ...grpc.CallOption) (*User, error) + SetUserSplitMode(ctx context.Context, in *UserSplitModeRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + LogoutUser(ctx context.Context, in *wrapperspb.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) + RemoveUser(ctx context.Context, in *wrapperspb.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) + ConfigureUserAppleMail(ctx context.Context, in *ConfigureAppleMailRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + // Server -> Client event stream + StartEventStream(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (Bridge_StartEventStreamClient, error) + StopEventStream(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) +} + +type bridgeClient struct { + cc grpc.ClientConnInterface +} + +func NewBridgeClient(cc grpc.ClientConnInterface) BridgeClient { + return &bridgeClient{cc} +} + +func (c *bridgeClient) GuiReady(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/grpc.Bridge/GuiReady", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) Quit(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/grpc.Bridge/Quit", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) Restart(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/grpc.Bridge/Restart", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) ShowOnStartup(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) { + out := new(wrapperspb.BoolValue) + err := c.cc.Invoke(ctx, "/grpc.Bridge/ShowOnStartup", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) ShowSplashScreen(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) { + out := new(wrapperspb.BoolValue) + err := c.cc.Invoke(ctx, "/grpc.Bridge/ShowSplashScreen", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) IsFirstGuiStart(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) { + out := new(wrapperspb.BoolValue) + err := c.cc.Invoke(ctx, "/grpc.Bridge/IsFirstGuiStart", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) SetIsAutostartOn(ctx context.Context, in *wrapperspb.BoolValue, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/grpc.Bridge/SetIsAutostartOn", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) IsAutostartOn(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) { + out := new(wrapperspb.BoolValue) + err := c.cc.Invoke(ctx, "/grpc.Bridge/IsAutostartOn", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) SetIsBetaEnabled(ctx context.Context, in *wrapperspb.BoolValue, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/grpc.Bridge/SetIsBetaEnabled", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) IsBetaEnabled(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) { + out := new(wrapperspb.BoolValue) + err := c.cc.Invoke(ctx, "/grpc.Bridge/IsBetaEnabled", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) GoOs(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) { + out := new(wrapperspb.StringValue) + err := c.cc.Invoke(ctx, "/grpc.Bridge/GoOs", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) TriggerReset(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/grpc.Bridge/TriggerReset", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) Version(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) { + out := new(wrapperspb.StringValue) + err := c.cc.Invoke(ctx, "/grpc.Bridge/Version", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) LogsPath(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) { + out := new(wrapperspb.StringValue) + err := c.cc.Invoke(ctx, "/grpc.Bridge/LogsPath", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) LicensePath(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) { + out := new(wrapperspb.StringValue) + err := c.cc.Invoke(ctx, "/grpc.Bridge/LicensePath", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) DependencyLicensesLink(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) { + out := new(wrapperspb.StringValue) + err := c.cc.Invoke(ctx, "/grpc.Bridge/DependencyLicensesLink", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) SetColorSchemeName(ctx context.Context, in *wrapperspb.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/grpc.Bridge/SetColorSchemeName", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) ColorSchemeName(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) { + out := new(wrapperspb.StringValue) + err := c.cc.Invoke(ctx, "/grpc.Bridge/ColorSchemeName", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) CurrentEmailClient(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) { + out := new(wrapperspb.StringValue) + err := c.cc.Invoke(ctx, "/grpc.Bridge/CurrentEmailClient", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) ReportBug(ctx context.Context, in *ReportBugRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/grpc.Bridge/ReportBug", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) Login(ctx context.Context, in *LoginRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/grpc.Bridge/Login", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) Login2FA(ctx context.Context, in *LoginRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/grpc.Bridge/Login2FA", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) Login2Passwords(ctx context.Context, in *LoginRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/grpc.Bridge/Login2Passwords", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) LoginAbort(ctx context.Context, in *LoginAbortRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/grpc.Bridge/LoginAbort", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) CheckUpdate(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/grpc.Bridge/CheckUpdate", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) InstallUpdate(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/grpc.Bridge/InstallUpdate", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) SetIsAutomaticUpdateOn(ctx context.Context, in *wrapperspb.BoolValue, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/grpc.Bridge/SetIsAutomaticUpdateOn", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) IsAutomaticUpdateOn(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) { + out := new(wrapperspb.BoolValue) + err := c.cc.Invoke(ctx, "/grpc.Bridge/IsAutomaticUpdateOn", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) IsCacheOnDiskEnabled(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) { + out := new(wrapperspb.BoolValue) + err := c.cc.Invoke(ctx, "/grpc.Bridge/IsCacheOnDiskEnabled", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) DiskCachePath(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) { + out := new(wrapperspb.StringValue) + err := c.cc.Invoke(ctx, "/grpc.Bridge/DiskCachePath", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) ChangeLocalCache(ctx context.Context, in *ChangeLocalCacheRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/grpc.Bridge/ChangeLocalCache", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) SetIsDoHEnabled(ctx context.Context, in *wrapperspb.BoolValue, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/grpc.Bridge/SetIsDoHEnabled", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) IsDoHEnabled(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) { + out := new(wrapperspb.BoolValue) + err := c.cc.Invoke(ctx, "/grpc.Bridge/IsDoHEnabled", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) SetUseSslForSmtp(ctx context.Context, in *wrapperspb.BoolValue, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/grpc.Bridge/SetUseSslForSmtp", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) UseSslForSmtp(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) { + out := new(wrapperspb.BoolValue) + err := c.cc.Invoke(ctx, "/grpc.Bridge/UseSslForSmtp", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) Hostname(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) { + out := new(wrapperspb.StringValue) + err := c.cc.Invoke(ctx, "/grpc.Bridge/Hostname", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) ImapPort(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.Int32Value, error) { + out := new(wrapperspb.Int32Value) + err := c.cc.Invoke(ctx, "/grpc.Bridge/ImapPort", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) SmtpPort(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.Int32Value, error) { + out := new(wrapperspb.Int32Value) + err := c.cc.Invoke(ctx, "/grpc.Bridge/SmtpPort", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) ChangePorts(ctx context.Context, in *ChangePortsRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/grpc.Bridge/ChangePorts", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) IsPortFree(ctx context.Context, in *wrapperspb.Int32Value, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) { + out := new(wrapperspb.BoolValue) + err := c.cc.Invoke(ctx, "/grpc.Bridge/IsPortFree", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) AvailableKeychains(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*AvailableKeychainsResponse, error) { + out := new(AvailableKeychainsResponse) + err := c.cc.Invoke(ctx, "/grpc.Bridge/AvailableKeychains", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) SetCurrentKeychain(ctx context.Context, in *wrapperspb.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/grpc.Bridge/SetCurrentKeychain", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) CurrentKeychain(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) { + out := new(wrapperspb.StringValue) + err := c.cc.Invoke(ctx, "/grpc.Bridge/CurrentKeychain", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) GetUserList(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*UserListResponse, error) { + out := new(UserListResponse) + err := c.cc.Invoke(ctx, "/grpc.Bridge/GetUserList", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) GetUser(ctx context.Context, in *wrapperspb.StringValue, opts ...grpc.CallOption) (*User, error) { + out := new(User) + err := c.cc.Invoke(ctx, "/grpc.Bridge/GetUser", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) SetUserSplitMode(ctx context.Context, in *UserSplitModeRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/grpc.Bridge/SetUserSplitMode", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) LogoutUser(ctx context.Context, in *wrapperspb.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/grpc.Bridge/LogoutUser", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) RemoveUser(ctx context.Context, in *wrapperspb.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/grpc.Bridge/RemoveUser", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) ConfigureUserAppleMail(ctx context.Context, in *ConfigureAppleMailRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/grpc.Bridge/ConfigureUserAppleMail", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) StartEventStream(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (Bridge_StartEventStreamClient, error) { + stream, err := c.cc.NewStream(ctx, &Bridge_ServiceDesc.Streams[0], "/grpc.Bridge/StartEventStream", opts...) + if err != nil { + return nil, err + } + x := &bridgeStartEventStreamClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type Bridge_StartEventStreamClient interface { + Recv() (*StreamEvent, error) + grpc.ClientStream +} + +type bridgeStartEventStreamClient struct { + grpc.ClientStream +} + +func (x *bridgeStartEventStreamClient) Recv() (*StreamEvent, error) { + m := new(StreamEvent) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *bridgeClient) StopEventStream(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/grpc.Bridge/StopEventStream", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// BridgeServer is the server API for Bridge service. +// All implementations must embed UnimplementedBridgeServer +// for forward compatibility +type BridgeServer interface { + // App related calls + GuiReady(context.Context, *emptypb.Empty) (*emptypb.Empty, error) + Quit(context.Context, *emptypb.Empty) (*emptypb.Empty, error) + Restart(context.Context, *emptypb.Empty) (*emptypb.Empty, error) + ShowOnStartup(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) + ShowSplashScreen(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) + IsFirstGuiStart(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) + SetIsAutostartOn(context.Context, *wrapperspb.BoolValue) (*emptypb.Empty, error) + IsAutostartOn(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) + SetIsBetaEnabled(context.Context, *wrapperspb.BoolValue) (*emptypb.Empty, error) + IsBetaEnabled(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) + GoOs(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) + TriggerReset(context.Context, *emptypb.Empty) (*emptypb.Empty, error) + Version(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) + LogsPath(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) + LicensePath(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) + // rpc ReleaseNotesLink(google.protobuf.Empty) returns (google.protobuf.StringValue); // TODO Apparently cannot be polled for now, will be sent as update. + DependencyLicensesLink(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) + // rpc LandingPageLink(google.protobuf.Empty) returns (google.protobuf.StringValue); // TODO Apparently cannot be polled for now, will be sent as update. + SetColorSchemeName(context.Context, *wrapperspb.StringValue) (*emptypb.Empty, error) + ColorSchemeName(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) + CurrentEmailClient(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) + ReportBug(context.Context, *ReportBugRequest) (*emptypb.Empty, error) + // login + Login(context.Context, *LoginRequest) (*emptypb.Empty, error) + Login2FA(context.Context, *LoginRequest) (*emptypb.Empty, error) + Login2Passwords(context.Context, *LoginRequest) (*emptypb.Empty, error) + LoginAbort(context.Context, *LoginAbortRequest) (*emptypb.Empty, error) + // update + CheckUpdate(context.Context, *emptypb.Empty) (*emptypb.Empty, error) + InstallUpdate(context.Context, *emptypb.Empty) (*emptypb.Empty, error) + SetIsAutomaticUpdateOn(context.Context, *wrapperspb.BoolValue) (*emptypb.Empty, error) + IsAutomaticUpdateOn(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) + // cache + IsCacheOnDiskEnabled(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) + DiskCachePath(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) + ChangeLocalCache(context.Context, *ChangeLocalCacheRequest) (*emptypb.Empty, error) + // mail + SetIsDoHEnabled(context.Context, *wrapperspb.BoolValue) (*emptypb.Empty, error) + IsDoHEnabled(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) + SetUseSslForSmtp(context.Context, *wrapperspb.BoolValue) (*emptypb.Empty, error) + UseSslForSmtp(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) + Hostname(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) + ImapPort(context.Context, *emptypb.Empty) (*wrapperspb.Int32Value, error) + SmtpPort(context.Context, *emptypb.Empty) (*wrapperspb.Int32Value, error) + ChangePorts(context.Context, *ChangePortsRequest) (*emptypb.Empty, error) + IsPortFree(context.Context, *wrapperspb.Int32Value) (*wrapperspb.BoolValue, error) + // keychain + AvailableKeychains(context.Context, *emptypb.Empty) (*AvailableKeychainsResponse, error) + SetCurrentKeychain(context.Context, *wrapperspb.StringValue) (*emptypb.Empty, error) + CurrentKeychain(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) + // User & user list + GetUserList(context.Context, *emptypb.Empty) (*UserListResponse, error) + GetUser(context.Context, *wrapperspb.StringValue) (*User, error) + SetUserSplitMode(context.Context, *UserSplitModeRequest) (*emptypb.Empty, error) + LogoutUser(context.Context, *wrapperspb.StringValue) (*emptypb.Empty, error) + RemoveUser(context.Context, *wrapperspb.StringValue) (*emptypb.Empty, error) + ConfigureUserAppleMail(context.Context, *ConfigureAppleMailRequest) (*emptypb.Empty, error) + // Server -> Client event stream + StartEventStream(*emptypb.Empty, Bridge_StartEventStreamServer) error + StopEventStream(context.Context, *emptypb.Empty) (*emptypb.Empty, error) + mustEmbedUnimplementedBridgeServer() +} + +// UnimplementedBridgeServer must be embedded to have forward compatible implementations. +type UnimplementedBridgeServer struct { +} + +func (UnimplementedBridgeServer) GuiReady(context.Context, *emptypb.Empty) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method GuiReady not implemented") +} +func (UnimplementedBridgeServer) Quit(context.Context, *emptypb.Empty) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method Quit not implemented") +} +func (UnimplementedBridgeServer) Restart(context.Context, *emptypb.Empty) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method Restart not implemented") +} +func (UnimplementedBridgeServer) ShowOnStartup(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) { + return nil, status.Errorf(codes.Unimplemented, "method ShowOnStartup not implemented") +} +func (UnimplementedBridgeServer) ShowSplashScreen(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) { + return nil, status.Errorf(codes.Unimplemented, "method ShowSplashScreen not implemented") +} +func (UnimplementedBridgeServer) IsFirstGuiStart(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) { + return nil, status.Errorf(codes.Unimplemented, "method IsFirstGuiStart not implemented") +} +func (UnimplementedBridgeServer) SetIsAutostartOn(context.Context, *wrapperspb.BoolValue) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetIsAutostartOn not implemented") +} +func (UnimplementedBridgeServer) IsAutostartOn(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) { + return nil, status.Errorf(codes.Unimplemented, "method IsAutostartOn not implemented") +} +func (UnimplementedBridgeServer) SetIsBetaEnabled(context.Context, *wrapperspb.BoolValue) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetIsBetaEnabled not implemented") +} +func (UnimplementedBridgeServer) IsBetaEnabled(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) { + return nil, status.Errorf(codes.Unimplemented, "method IsBetaEnabled not implemented") +} +func (UnimplementedBridgeServer) GoOs(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) { + return nil, status.Errorf(codes.Unimplemented, "method GoOs not implemented") +} +func (UnimplementedBridgeServer) TriggerReset(context.Context, *emptypb.Empty) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method TriggerReset not implemented") +} +func (UnimplementedBridgeServer) Version(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) { + return nil, status.Errorf(codes.Unimplemented, "method Version not implemented") +} +func (UnimplementedBridgeServer) LogsPath(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) { + return nil, status.Errorf(codes.Unimplemented, "method LogsPath not implemented") +} +func (UnimplementedBridgeServer) LicensePath(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) { + return nil, status.Errorf(codes.Unimplemented, "method LicensePath not implemented") +} +func (UnimplementedBridgeServer) DependencyLicensesLink(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) { + return nil, status.Errorf(codes.Unimplemented, "method DependencyLicensesLink not implemented") +} +func (UnimplementedBridgeServer) SetColorSchemeName(context.Context, *wrapperspb.StringValue) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetColorSchemeName not implemented") +} +func (UnimplementedBridgeServer) ColorSchemeName(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) { + return nil, status.Errorf(codes.Unimplemented, "method ColorSchemeName not implemented") +} +func (UnimplementedBridgeServer) CurrentEmailClient(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) { + return nil, status.Errorf(codes.Unimplemented, "method CurrentEmailClient not implemented") +} +func (UnimplementedBridgeServer) ReportBug(context.Context, *ReportBugRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method ReportBug not implemented") +} +func (UnimplementedBridgeServer) Login(context.Context, *LoginRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method Login not implemented") +} +func (UnimplementedBridgeServer) Login2FA(context.Context, *LoginRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method Login2FA not implemented") +} +func (UnimplementedBridgeServer) Login2Passwords(context.Context, *LoginRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method Login2Passwords not implemented") +} +func (UnimplementedBridgeServer) LoginAbort(context.Context, *LoginAbortRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method LoginAbort not implemented") +} +func (UnimplementedBridgeServer) CheckUpdate(context.Context, *emptypb.Empty) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method CheckUpdate not implemented") +} +func (UnimplementedBridgeServer) InstallUpdate(context.Context, *emptypb.Empty) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method InstallUpdate not implemented") +} +func (UnimplementedBridgeServer) SetIsAutomaticUpdateOn(context.Context, *wrapperspb.BoolValue) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetIsAutomaticUpdateOn not implemented") +} +func (UnimplementedBridgeServer) IsAutomaticUpdateOn(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) { + return nil, status.Errorf(codes.Unimplemented, "method IsAutomaticUpdateOn not implemented") +} +func (UnimplementedBridgeServer) IsCacheOnDiskEnabled(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) { + return nil, status.Errorf(codes.Unimplemented, "method IsCacheOnDiskEnabled not implemented") +} +func (UnimplementedBridgeServer) DiskCachePath(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) { + return nil, status.Errorf(codes.Unimplemented, "method DiskCachePath not implemented") +} +func (UnimplementedBridgeServer) ChangeLocalCache(context.Context, *ChangeLocalCacheRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method ChangeLocalCache not implemented") +} +func (UnimplementedBridgeServer) SetIsDoHEnabled(context.Context, *wrapperspb.BoolValue) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetIsDoHEnabled not implemented") +} +func (UnimplementedBridgeServer) IsDoHEnabled(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) { + return nil, status.Errorf(codes.Unimplemented, "method IsDoHEnabled not implemented") +} +func (UnimplementedBridgeServer) SetUseSslForSmtp(context.Context, *wrapperspb.BoolValue) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetUseSslForSmtp not implemented") +} +func (UnimplementedBridgeServer) UseSslForSmtp(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) { + return nil, status.Errorf(codes.Unimplemented, "method UseSslForSmtp not implemented") +} +func (UnimplementedBridgeServer) Hostname(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) { + return nil, status.Errorf(codes.Unimplemented, "method Hostname not implemented") +} +func (UnimplementedBridgeServer) ImapPort(context.Context, *emptypb.Empty) (*wrapperspb.Int32Value, error) { + return nil, status.Errorf(codes.Unimplemented, "method ImapPort not implemented") +} +func (UnimplementedBridgeServer) SmtpPort(context.Context, *emptypb.Empty) (*wrapperspb.Int32Value, error) { + return nil, status.Errorf(codes.Unimplemented, "method SmtpPort not implemented") +} +func (UnimplementedBridgeServer) ChangePorts(context.Context, *ChangePortsRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method ChangePorts not implemented") +} +func (UnimplementedBridgeServer) IsPortFree(context.Context, *wrapperspb.Int32Value) (*wrapperspb.BoolValue, error) { + return nil, status.Errorf(codes.Unimplemented, "method IsPortFree not implemented") +} +func (UnimplementedBridgeServer) AvailableKeychains(context.Context, *emptypb.Empty) (*AvailableKeychainsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AvailableKeychains not implemented") +} +func (UnimplementedBridgeServer) SetCurrentKeychain(context.Context, *wrapperspb.StringValue) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetCurrentKeychain not implemented") +} +func (UnimplementedBridgeServer) CurrentKeychain(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) { + return nil, status.Errorf(codes.Unimplemented, "method CurrentKeychain not implemented") +} +func (UnimplementedBridgeServer) GetUserList(context.Context, *emptypb.Empty) (*UserListResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetUserList not implemented") +} +func (UnimplementedBridgeServer) GetUser(context.Context, *wrapperspb.StringValue) (*User, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetUser not implemented") +} +func (UnimplementedBridgeServer) SetUserSplitMode(context.Context, *UserSplitModeRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetUserSplitMode not implemented") +} +func (UnimplementedBridgeServer) LogoutUser(context.Context, *wrapperspb.StringValue) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method LogoutUser not implemented") +} +func (UnimplementedBridgeServer) RemoveUser(context.Context, *wrapperspb.StringValue) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method RemoveUser not implemented") +} +func (UnimplementedBridgeServer) ConfigureUserAppleMail(context.Context, *ConfigureAppleMailRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method ConfigureUserAppleMail not implemented") +} +func (UnimplementedBridgeServer) StartEventStream(*emptypb.Empty, Bridge_StartEventStreamServer) error { + return status.Errorf(codes.Unimplemented, "method StartEventStream not implemented") +} +func (UnimplementedBridgeServer) StopEventStream(context.Context, *emptypb.Empty) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method StopEventStream not implemented") +} +func (UnimplementedBridgeServer) mustEmbedUnimplementedBridgeServer() {} + +// UnsafeBridgeServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to BridgeServer will +// result in compilation errors. +type UnsafeBridgeServer interface { + mustEmbedUnimplementedBridgeServer() +} + +func RegisterBridgeServer(s grpc.ServiceRegistrar, srv BridgeServer) { + s.RegisterService(&Bridge_ServiceDesc, srv) +} + +func _Bridge_GuiReady_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).GuiReady(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/GuiReady", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).GuiReady(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_Quit_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).Quit(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/Quit", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).Quit(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_Restart_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).Restart(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/Restart", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).Restart(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_ShowOnStartup_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).ShowOnStartup(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/ShowOnStartup", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).ShowOnStartup(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_ShowSplashScreen_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).ShowSplashScreen(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/ShowSplashScreen", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).ShowSplashScreen(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_IsFirstGuiStart_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).IsFirstGuiStart(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/IsFirstGuiStart", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).IsFirstGuiStart(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_SetIsAutostartOn_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(wrapperspb.BoolValue) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).SetIsAutostartOn(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/SetIsAutostartOn", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).SetIsAutostartOn(ctx, req.(*wrapperspb.BoolValue)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_IsAutostartOn_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).IsAutostartOn(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/IsAutostartOn", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).IsAutostartOn(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_SetIsBetaEnabled_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(wrapperspb.BoolValue) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).SetIsBetaEnabled(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/SetIsBetaEnabled", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).SetIsBetaEnabled(ctx, req.(*wrapperspb.BoolValue)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_IsBetaEnabled_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).IsBetaEnabled(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/IsBetaEnabled", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).IsBetaEnabled(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_GoOs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).GoOs(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/GoOs", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).GoOs(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_TriggerReset_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).TriggerReset(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/TriggerReset", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).TriggerReset(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_Version_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).Version(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/Version", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).Version(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_LogsPath_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).LogsPath(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/LogsPath", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).LogsPath(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_LicensePath_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).LicensePath(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/LicensePath", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).LicensePath(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_DependencyLicensesLink_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).DependencyLicensesLink(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/DependencyLicensesLink", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).DependencyLicensesLink(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_SetColorSchemeName_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(wrapperspb.StringValue) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).SetColorSchemeName(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/SetColorSchemeName", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).SetColorSchemeName(ctx, req.(*wrapperspb.StringValue)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_ColorSchemeName_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).ColorSchemeName(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/ColorSchemeName", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).ColorSchemeName(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_CurrentEmailClient_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).CurrentEmailClient(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/CurrentEmailClient", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).CurrentEmailClient(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_ReportBug_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ReportBugRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).ReportBug(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/ReportBug", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).ReportBug(ctx, req.(*ReportBugRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_Login_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(LoginRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).Login(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/Login", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).Login(ctx, req.(*LoginRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_Login2FA_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(LoginRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).Login2FA(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/Login2FA", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).Login2FA(ctx, req.(*LoginRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_Login2Passwords_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(LoginRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).Login2Passwords(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/Login2Passwords", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).Login2Passwords(ctx, req.(*LoginRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_LoginAbort_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(LoginAbortRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).LoginAbort(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/LoginAbort", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).LoginAbort(ctx, req.(*LoginAbortRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_CheckUpdate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).CheckUpdate(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/CheckUpdate", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).CheckUpdate(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_InstallUpdate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).InstallUpdate(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/InstallUpdate", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).InstallUpdate(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_SetIsAutomaticUpdateOn_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(wrapperspb.BoolValue) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).SetIsAutomaticUpdateOn(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/SetIsAutomaticUpdateOn", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).SetIsAutomaticUpdateOn(ctx, req.(*wrapperspb.BoolValue)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_IsAutomaticUpdateOn_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).IsAutomaticUpdateOn(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/IsAutomaticUpdateOn", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).IsAutomaticUpdateOn(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_IsCacheOnDiskEnabled_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).IsCacheOnDiskEnabled(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/IsCacheOnDiskEnabled", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).IsCacheOnDiskEnabled(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_DiskCachePath_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).DiskCachePath(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/DiskCachePath", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).DiskCachePath(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_ChangeLocalCache_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ChangeLocalCacheRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).ChangeLocalCache(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/ChangeLocalCache", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).ChangeLocalCache(ctx, req.(*ChangeLocalCacheRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_SetIsDoHEnabled_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(wrapperspb.BoolValue) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).SetIsDoHEnabled(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/SetIsDoHEnabled", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).SetIsDoHEnabled(ctx, req.(*wrapperspb.BoolValue)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_IsDoHEnabled_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).IsDoHEnabled(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/IsDoHEnabled", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).IsDoHEnabled(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_SetUseSslForSmtp_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(wrapperspb.BoolValue) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).SetUseSslForSmtp(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/SetUseSslForSmtp", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).SetUseSslForSmtp(ctx, req.(*wrapperspb.BoolValue)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_UseSslForSmtp_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).UseSslForSmtp(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/UseSslForSmtp", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).UseSslForSmtp(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_Hostname_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).Hostname(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/Hostname", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).Hostname(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_ImapPort_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).ImapPort(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/ImapPort", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).ImapPort(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_SmtpPort_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).SmtpPort(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/SmtpPort", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).SmtpPort(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_ChangePorts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ChangePortsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).ChangePorts(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/ChangePorts", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).ChangePorts(ctx, req.(*ChangePortsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_IsPortFree_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(wrapperspb.Int32Value) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).IsPortFree(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/IsPortFree", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).IsPortFree(ctx, req.(*wrapperspb.Int32Value)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_AvailableKeychains_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).AvailableKeychains(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/AvailableKeychains", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).AvailableKeychains(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_SetCurrentKeychain_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(wrapperspb.StringValue) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).SetCurrentKeychain(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/SetCurrentKeychain", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).SetCurrentKeychain(ctx, req.(*wrapperspb.StringValue)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_CurrentKeychain_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).CurrentKeychain(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/CurrentKeychain", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).CurrentKeychain(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_GetUserList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).GetUserList(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/GetUserList", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).GetUserList(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_GetUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(wrapperspb.StringValue) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).GetUser(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/GetUser", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).GetUser(ctx, req.(*wrapperspb.StringValue)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_SetUserSplitMode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UserSplitModeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).SetUserSplitMode(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/SetUserSplitMode", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).SetUserSplitMode(ctx, req.(*UserSplitModeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_LogoutUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(wrapperspb.StringValue) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).LogoutUser(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/LogoutUser", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).LogoutUser(ctx, req.(*wrapperspb.StringValue)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_RemoveUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(wrapperspb.StringValue) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).RemoveUser(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/RemoveUser", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).RemoveUser(ctx, req.(*wrapperspb.StringValue)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_ConfigureUserAppleMail_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ConfigureAppleMailRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).ConfigureUserAppleMail(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/ConfigureUserAppleMail", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).ConfigureUserAppleMail(ctx, req.(*ConfigureAppleMailRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_StartEventStream_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(emptypb.Empty) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(BridgeServer).StartEventStream(m, &bridgeStartEventStreamServer{stream}) +} + +type Bridge_StartEventStreamServer interface { + Send(*StreamEvent) error + grpc.ServerStream +} + +type bridgeStartEventStreamServer struct { + grpc.ServerStream +} + +func (x *bridgeStartEventStreamServer) Send(m *StreamEvent) error { + return x.ServerStream.SendMsg(m) +} + +func _Bridge_StopEventStream_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).StopEventStream(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/StopEventStream", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).StopEventStream(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +// Bridge_ServiceDesc is the grpc.ServiceDesc for Bridge service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Bridge_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "grpc.Bridge", + HandlerType: (*BridgeServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GuiReady", + Handler: _Bridge_GuiReady_Handler, + }, + { + MethodName: "Quit", + Handler: _Bridge_Quit_Handler, + }, + { + MethodName: "Restart", + Handler: _Bridge_Restart_Handler, + }, + { + MethodName: "ShowOnStartup", + Handler: _Bridge_ShowOnStartup_Handler, + }, + { + MethodName: "ShowSplashScreen", + Handler: _Bridge_ShowSplashScreen_Handler, + }, + { + MethodName: "IsFirstGuiStart", + Handler: _Bridge_IsFirstGuiStart_Handler, + }, + { + MethodName: "SetIsAutostartOn", + Handler: _Bridge_SetIsAutostartOn_Handler, + }, + { + MethodName: "IsAutostartOn", + Handler: _Bridge_IsAutostartOn_Handler, + }, + { + MethodName: "SetIsBetaEnabled", + Handler: _Bridge_SetIsBetaEnabled_Handler, + }, + { + MethodName: "IsBetaEnabled", + Handler: _Bridge_IsBetaEnabled_Handler, + }, + { + MethodName: "GoOs", + Handler: _Bridge_GoOs_Handler, + }, + { + MethodName: "TriggerReset", + Handler: _Bridge_TriggerReset_Handler, + }, + { + MethodName: "Version", + Handler: _Bridge_Version_Handler, + }, + { + MethodName: "LogsPath", + Handler: _Bridge_LogsPath_Handler, + }, + { + MethodName: "LicensePath", + Handler: _Bridge_LicensePath_Handler, + }, + { + MethodName: "DependencyLicensesLink", + Handler: _Bridge_DependencyLicensesLink_Handler, + }, + { + MethodName: "SetColorSchemeName", + Handler: _Bridge_SetColorSchemeName_Handler, + }, + { + MethodName: "ColorSchemeName", + Handler: _Bridge_ColorSchemeName_Handler, + }, + { + MethodName: "CurrentEmailClient", + Handler: _Bridge_CurrentEmailClient_Handler, + }, + { + MethodName: "ReportBug", + Handler: _Bridge_ReportBug_Handler, + }, + { + MethodName: "Login", + Handler: _Bridge_Login_Handler, + }, + { + MethodName: "Login2FA", + Handler: _Bridge_Login2FA_Handler, + }, + { + MethodName: "Login2Passwords", + Handler: _Bridge_Login2Passwords_Handler, + }, + { + MethodName: "LoginAbort", + Handler: _Bridge_LoginAbort_Handler, + }, + { + MethodName: "CheckUpdate", + Handler: _Bridge_CheckUpdate_Handler, + }, + { + MethodName: "InstallUpdate", + Handler: _Bridge_InstallUpdate_Handler, + }, + { + MethodName: "SetIsAutomaticUpdateOn", + Handler: _Bridge_SetIsAutomaticUpdateOn_Handler, + }, + { + MethodName: "IsAutomaticUpdateOn", + Handler: _Bridge_IsAutomaticUpdateOn_Handler, + }, + { + MethodName: "IsCacheOnDiskEnabled", + Handler: _Bridge_IsCacheOnDiskEnabled_Handler, + }, + { + MethodName: "DiskCachePath", + Handler: _Bridge_DiskCachePath_Handler, + }, + { + MethodName: "ChangeLocalCache", + Handler: _Bridge_ChangeLocalCache_Handler, + }, + { + MethodName: "SetIsDoHEnabled", + Handler: _Bridge_SetIsDoHEnabled_Handler, + }, + { + MethodName: "IsDoHEnabled", + Handler: _Bridge_IsDoHEnabled_Handler, + }, + { + MethodName: "SetUseSslForSmtp", + Handler: _Bridge_SetUseSslForSmtp_Handler, + }, + { + MethodName: "UseSslForSmtp", + Handler: _Bridge_UseSslForSmtp_Handler, + }, + { + MethodName: "Hostname", + Handler: _Bridge_Hostname_Handler, + }, + { + MethodName: "ImapPort", + Handler: _Bridge_ImapPort_Handler, + }, + { + MethodName: "SmtpPort", + Handler: _Bridge_SmtpPort_Handler, + }, + { + MethodName: "ChangePorts", + Handler: _Bridge_ChangePorts_Handler, + }, + { + MethodName: "IsPortFree", + Handler: _Bridge_IsPortFree_Handler, + }, + { + MethodName: "AvailableKeychains", + Handler: _Bridge_AvailableKeychains_Handler, + }, + { + MethodName: "SetCurrentKeychain", + Handler: _Bridge_SetCurrentKeychain_Handler, + }, + { + MethodName: "CurrentKeychain", + Handler: _Bridge_CurrentKeychain_Handler, + }, + { + MethodName: "GetUserList", + Handler: _Bridge_GetUserList_Handler, + }, + { + MethodName: "GetUser", + Handler: _Bridge_GetUser_Handler, + }, + { + MethodName: "SetUserSplitMode", + Handler: _Bridge_SetUserSplitMode_Handler, + }, + { + MethodName: "LogoutUser", + Handler: _Bridge_LogoutUser_Handler, + }, + { + MethodName: "RemoveUser", + Handler: _Bridge_RemoveUser_Handler, + }, + { + MethodName: "ConfigureUserAppleMail", + Handler: _Bridge_ConfigureUserAppleMail_Handler, + }, + { + MethodName: "StopEventStream", + Handler: _Bridge_StopEventStream_Handler, + }, + }, + Streams: []grpc.StreamDesc{ + { + StreamName: "StartEventStream", + Handler: _Bridge_StartEventStream_Handler, + ServerStreams: true, + }, + }, + Metadata: "bridge.proto", +} diff --git a/internal/frontend/grpc/certs.go b/internal/frontend/grpc/certs.go new file mode 100644 index 00000000..b83a0cfb --- /dev/null +++ b/internal/frontend/grpc/certs.go @@ -0,0 +1,69 @@ +// Copyright (c) 2022 Proton AG +// +// This file is part of Proton Mail Bridge.Bridge. +// +// Proton Mail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Proton Mail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Proton Mail Bridge. If not, see . + +package grpc + +//goland:noinspection SpellCheckingInspection +const ( + serverCert = `-----BEGIN CERTIFICATE----- +MIIC5TCCAc2gAwIBAgIJAMUQK0VGexMsMA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNV +BAMMCWxvY2FsaG9zdDAeFw0yMjA2MTQxNjUyNTVaFw0yMjA3MTQxNjUyNTVaMBQx +EjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAL6T1JQ0jptq512PBLASpCLFB0px7KIzEml0oMUCkVgUF+2cayrvdBXJZnaO +SG+/JPnHDcQ/ecgqkh2Ii6a2x2kWA5KqWiV+bSHp0drXyUGJfM85muLsnrhYwJ83 +HHtweoUVebRZvHn66KjaH8nBJ+YVWyYbSUhJezcg6nBSEtkW+I/XUHu4S2C7FUc5 +DXPO3yWWZuZ22OZz70DY3uYE/9COuilotuKdj7XgeKDyKIvRXjPFyqGxwnnp6bXC +vWvrQdcxy0wM+vZxew3QtA/Ag9uKJU9owP6noauXw95l49lEVIA5KXVNtdaldVht +MO/QoelLZC7h79PK22zbii3x930CAwEAAaM6MDgwFAYDVR0RBA0wC4IJbG9jYWxo +b3N0MAsGA1UdDwQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0B +AQsFAAOCAQEAW/9PE8dcAN+0C3K96Xd6Y3qOOtQhRw+WlZXhtiqMtlJfTjvuGKs9 +58xuKcTvU5oobxLv+i5+4gpqLjUZZ9FBnYXZIACNVzq4PEXf+YdzcA+y6RS/rqT4 +dUjsuYrScAmdXK03Duw3HWYrTp8gsJzIaYGTltUrOn0E4k/TsZb/tZ6z+oH7Fi+p +wdsI6Ut6Zwm3Z7WLn5DDk8KvFjHjZkdsCb82SFSAUVrzWo5EtbLIY/7y3A5rGp9D +t0AVpuGPo5Vn+MW1WA9HT8lhjz0v5wKGMOBi3VYW+Yx8FWHDpacvbZwVM0MjMSAd +M7SXYbNDiLF4LwPLsunoLsW133Ky7s99MA== +-----END CERTIFICATE-----` + + serverKey = `-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC+k9SUNI6baudd +jwSwEqQixQdKceyiMxJpdKDFApFYFBftnGsq73QVyWZ2jkhvvyT5xw3EP3nIKpId +iIumtsdpFgOSqlolfm0h6dHa18lBiXzPOZri7J64WMCfNxx7cHqFFXm0Wbx5+uio +2h/JwSfmFVsmG0lISXs3IOpwUhLZFviP11B7uEtguxVHOQ1zzt8llmbmdtjmc+9A +2N7mBP/QjropaLbinY+14Hig8iiL0V4zxcqhscJ56em1wr1r60HXMctMDPr2cXsN +0LQPwIPbiiVPaMD+p6Grl8PeZePZRFSAOSl1TbXWpXVYbTDv0KHpS2Qu4e/Tytts +24ot8fd9AgMBAAECggEBAJFkGpOOnRU4s5YO3BavwgS8p9lFnLAJooxNa7GhSd0W +R0MBSEkTMU7FvaPI3L5T5xOfpoMHohLxV1Osrk3bt7oWD1e/GtLr5routejtIx8a +kttNKTriJhyhqSJOWy5ZGz+YqKbMpxuwLftTnVjAQX4o4MbrnjbFyHjAZdqW4sY2 +jLulfEdOave6nxaEocmIkoXEjuX90LB+yNG6ncSYM3GV+IyCVw7DsoU4dLd/IRDa +4iJVF7tVdAsZqN6/EVYXpGqG0t1HI8ddacHa1qWgCG3kBB+3faxXZcDJdlRrXLUQ +4jLH8oEfXOb5YgCwyYzW2EynXEpG5vjsPmsCWJY/mIECgYEA52av81+lui97KLg+ +T07XtR8zJPMkHnBNfc6ooWku/+0NuQPpUq14vqzRVut9jBHUDP3xSvrPnXsp15ZA +/mipLQLNKssTYtk90cyGqLUkrd/NPLFZLXToBfWBlfazdcJQQRIxZ2dTy5MH+HIU +Oio3LZi+iDIbdzzSlmL8PaLit20CgYEA0tYsswhq6OaWx25iu4hBMRlt6hr9qGVW +jlzCFjBhlh3YtoBti2w2fsJdU+hUpeXU327fhFmdCQFXtf+Om5CSHihmJ+mHj9O1 +5Jd6zn4o8szdg5je9T4gt7KG6QdXaFJ2aMuq+SxZl1NIE+9qnf/qom4GHHZ/Nj41 +vwlQu+zS5lECgYAOzSK0DoorPp5CHIbfy8tAap563pKQ394VDgL7UB8Rf7hA/V8P +SslOaP9679U4AGvv6M5mXWSqThZ/E71UiJ1Jo8Q72IGE8SBjKxHx+KQ/+vDF0RJD +NhchSnLfhMg14BgCEYfXdWSGwQDhg2qHzet5nyuQyqO3HMzbkblQt/qIgQKBgHLv +nPiQmy+SHRplO9+93MQ2d6wKwMNfUztSp9/OyjQ62xxKkO1TtbWOobAPVK4Hx+9y +EtmkvK3fFIC763M08eMM5PvXHDa1FFCkn6cYMZyDQDLwUINjNhTOdytr/CN76N8i +QHeLzN9o4D814mp1y+R2lFBJ7PmWGlilbGS2KxaxAoGAFMsb1MER+eTOUO3z05Di +lts4VRWQhq2frd/on6AcTv4idQox1RcOrKWQbRVgeQVY1SkkHhg8lN0jX3W3EfuQ +aOfyky04GbLiwO8NRHZMlORWLxlCkrUrb6Va+LQlT0JvpQbqdbu6Ix8NomG9K697 +aScKmY7bGC0ki2IIdt2YZ5I= +-----END PRIVATE KEY-----` +) diff --git a/internal/frontend/grpc/event_factory.go b/internal/frontend/grpc/event_factory.go new file mode 100644 index 00000000..6b9239c9 --- /dev/null +++ b/internal/frontend/grpc/event_factory.go @@ -0,0 +1,199 @@ +// Copyright (c) 2022 Proton AG +// +// This file is part of Proton Mail Bridge.Bridge. +// +// Proton Mail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Proton Mail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Proton Mail Bridge. If not, see . + +package grpc + +func NewInternetStatusEvent(connected bool) *StreamEvent { + return appEvent(&AppEvent{Event: &AppEvent_InternetStatus{InternetStatus: &InternetStatusEvent{Connected: connected}}}) +} + +func NewToggleAutostartFinishedEvent() *StreamEvent { + return appEvent(&AppEvent{Event: &AppEvent_ToggleAutostartFinished{ToggleAutostartFinished: &ToggleAutostartFinishedEvent{}}}) +} + +func NewResetFinishedEvent() *StreamEvent { + return appEvent(&AppEvent{Event: &AppEvent_ResetFinished{ResetFinished: &ResetFinishedEvent{}}}) +} + +func NewReportBugFinishedEvent() *StreamEvent { + return appEvent(&AppEvent{Event: &AppEvent_ReportBugFinished{ReportBugFinished: &ReportBugFinishedEvent{}}}) +} + +func NewReportBugSuccessEvent() *StreamEvent { + return appEvent(&AppEvent{Event: &AppEvent_ReportBugSuccess{ReportBugSuccess: &ReportBugSuccessEvent{}}}) +} + +func NewReportBugErrorEvent() *StreamEvent { + return appEvent(&AppEvent{Event: &AppEvent_ReportBugError{ReportBugError: &ReportBugErrorEvent{}}}) +} + +func NewShowMainWindowEvent() *StreamEvent { + return appEvent(&AppEvent{Event: &AppEvent_ShowMainWindow{ShowMainWindow: &ShowMainWindowEvent{}}}) +} + +func NewLoginError(err LoginErrorType, message string) *StreamEvent { + return loginEvent(&LoginEvent{Event: &LoginEvent_Error{Error: &LoginErrorEvent{Type: err, Message: message}}}) +} + +func NewLoginTfaRequestedEvent(username string) *StreamEvent { + return loginEvent(&LoginEvent{Event: &LoginEvent_TfaRequested{TfaRequested: &LoginTfaRequestedEvent{Username: username}}}) +} + +func NewLoginTwoPasswordsRequestedEvent() *StreamEvent { + return loginEvent(&LoginEvent{Event: &LoginEvent_TwoPasswordRequested{}}) +} + +func NewLoginFinishedEvent(userID string) *StreamEvent { + return loginEvent(&LoginEvent{Event: &LoginEvent_Finished{Finished: &LoginFinishedEvent{UserID: userID}}}) +} + +func NewLoginAlreadyLoggedInEvent(userID string) *StreamEvent { + return loginEvent(&LoginEvent{Event: &LoginEvent_AlreadyLoggedIn{AlreadyLoggedIn: &LoginFinishedEvent{UserID: userID}}}) +} + +func NewUpdateErrorEvent(errorType UpdateErrorType) *StreamEvent { + return updateEvent(&UpdateEvent{Event: &UpdateEvent_Error{Error: &UpdateErrorEvent{Type: errorType}}}) +} + +func NewUpdateManualReadyEvent(version string) *StreamEvent { + return updateEvent(&UpdateEvent{Event: &UpdateEvent_ManualReady{ManualReady: &UpdateManualReadyEvent{Version: version}}}) +} + +func NewUpdateManualRestartNeededEvent() *StreamEvent { + return updateEvent(&UpdateEvent{Event: &UpdateEvent_ManualRestartNeeded{ManualRestartNeeded: &UpdateManualRestartNeededEvent{}}}) +} + +func NewUpdateForceEvent(version string) *StreamEvent { + return updateEvent(&UpdateEvent{Event: &UpdateEvent_Force{Force: &UpdateForceEvent{Version: version}}}) +} + +func NewUpdateSilentRestartNeededEvent() *StreamEvent { + return updateEvent(&UpdateEvent{Event: &UpdateEvent_SilentRestartNeeded{SilentRestartNeeded: &UpdateSilentRestartNeeded{}}}) +} + +func NewUpdateIsLatestVersionEvent() *StreamEvent { + return updateEvent(&UpdateEvent{Event: &UpdateEvent_IsLatestVersion{IsLatestVersion: &UpdateIsLatestVersion{}}}) +} + +func NewUpdateCheckFinishedEvent() *StreamEvent { + return updateEvent(&UpdateEvent{Event: &UpdateEvent_CheckFinished{CheckFinished: &UpdateCheckFinished{}}}) +} + +func NewCacheErrorEvent(err CacheErrorType) *StreamEvent { + return cacheEvent(&CacheEvent{Event: &CacheEvent_Error{Error: &CacheErrorEvent{Type: err}}}) +} + +func NewCacheLocationChangeSuccessEvent() *StreamEvent { + return cacheEvent(&CacheEvent{Event: &CacheEvent_LocationChangedSuccess{LocationChangedSuccess: &CacheLocationChangeSuccessEvent{}}}) +} + +func NewCacheChangeLocalCacheFinishedEvent() *StreamEvent { + return cacheEvent(&CacheEvent{Event: &CacheEvent_ChangeLocalCacheFinished{ChangeLocalCacheFinished: &ChangeLocalCacheFinishedEvent{}}}) +} + +func NewIsCacheOnDiskEnabledChanged(enabled bool) *StreamEvent { + return cacheEvent(&CacheEvent{Event: &CacheEvent_IsCacheOnDiskEnabledChanged{IsCacheOnDiskEnabledChanged: &IsCacheOnDiskEnabledChanged{Enabled: enabled}}}) +} + +func NewDiskCachePathChanged(path string) *StreamEvent { + return cacheEvent(&CacheEvent{Event: &CacheEvent_DiskCachePathChanged{DiskCachePathChanged: &DiskCachePathChanged{Path: path}}}) +} +func NewMailSettingsErrorEvent(err MailSettingsErrorType) *StreamEvent { + return mailSettingsEvent(&MailSettingsEvent{Event: &MailSettingsEvent_Error{Error: &MailSettingsErrorEvent{Type: err}}}) +} + +func NewMailSettingsUseSslForSmtpFinishedEvent() *StreamEvent { //nolint:revive,stylecheck + return mailSettingsEvent(&MailSettingsEvent{Event: &MailSettingsEvent_UseSslForSmtpFinished{UseSslForSmtpFinished: &UseSslForSmtpFinishedEvent{}}}) +} + +func NewMailSettingsChangePortFinishedEvent() *StreamEvent { + return mailSettingsEvent(&MailSettingsEvent{Event: &MailSettingsEvent_ChangePortsFinished{ChangePortsFinished: &ChangePortsFinishedEvent{}}}) +} + +func NewKeychainChangeKeychainFinishedEvent() *StreamEvent { + return keychainEvent(&KeychainEvent{Event: &KeychainEvent_ChangeKeychainFinished{ChangeKeychainFinished: &ChangeKeychainFinishedEvent{}}}) +} + +func NewKeychainHasNoKeychainEvent() *StreamEvent { + return keychainEvent(&KeychainEvent{Event: &KeychainEvent_HasNoKeychain{HasNoKeychain: &HasNoKeychainEvent{}}}) +} + +func NewKeychainRebuildKeychainEvent() *StreamEvent { + return keychainEvent(&KeychainEvent{Event: &KeychainEvent_RebuildKeychain{RebuildKeychain: &RebuildKeychainEvent{}}}) +} + +func NewMailNoActiveKeyForRecipientEvent(email string) *StreamEvent { + return mailEvent(&MailEvent{Event: &MailEvent_NoActiveKeyForRecipientEvent{NoActiveKeyForRecipientEvent: &NoActiveKeyForRecipientEvent{Email: email}}}) +} + +func NewMailAddressChangeEvent(email string) *StreamEvent { + return mailEvent(&MailEvent{Event: &MailEvent_AddressChanged{AddressChanged: &AddressChangedEvent{Address: email}}}) +} + +func NewMailAddressChangeLogoutEvent(email string) *StreamEvent { + return mailEvent(&MailEvent{Event: &MailEvent_AddressChangedLogout{AddressChangedLogout: &AddressChangedLogoutEvent{Address: email}}}) +} + +func NewMailApiCertIssue() *StreamEvent { //nolint:revive,stylecheck + return mailEvent(&MailEvent{Event: &MailEvent_ApiCertIssue{ApiCertIssue: &ApiCertIssueEvent{}}}) +} + +func NewUserToggleSplitModeFinishedEvent(userID string) *StreamEvent { + return userEvent(&UserEvent{Event: &UserEvent_ToggleSplitModeFinished{ToggleSplitModeFinished: &ToggleSplitModeFinishedEvent{UserID: userID}}}) +} + +func NewUserDisconnectedEvent(email string) *StreamEvent { + return userEvent(&UserEvent{Event: &UserEvent_UserDisconnected{UserDisconnected: &UserDisconnectedEvent{Username: email}}}) +} + +func NewUserChangedEvent(userID string) *StreamEvent { + return userEvent(&UserEvent{Event: &UserEvent_UserChanged{UserChanged: &UserChangedEvent{UserID: userID}}}) +} + +// Event category factory functions. + +func appEvent(appEvent *AppEvent) *StreamEvent { + return &StreamEvent{Event: &StreamEvent_App{App: appEvent}} +} + +func loginEvent(event *LoginEvent) *StreamEvent { + return &StreamEvent{Event: &StreamEvent_Login{Login: event}} +} + +func updateEvent(event *UpdateEvent) *StreamEvent { + return &StreamEvent{Event: &StreamEvent_Update{Update: event}} +} + +func cacheEvent(event *CacheEvent) *StreamEvent { + return &StreamEvent{Event: &StreamEvent_Cache{Cache: event}} +} + +func mailSettingsEvent(event *MailSettingsEvent) *StreamEvent { + return &StreamEvent{Event: &StreamEvent_MailSettings{MailSettings: event}} +} + +func keychainEvent(event *KeychainEvent) *StreamEvent { + return &StreamEvent{Event: &StreamEvent_Keychain{Keychain: event}} +} + +func mailEvent(event *MailEvent) *StreamEvent { + return &StreamEvent{Event: &StreamEvent_Mail{Mail: event}} +} + +func userEvent(event *UserEvent) *StreamEvent { + return &StreamEvent{Event: &StreamEvent_User{User: event}} +} diff --git a/internal/frontend/grpc/service.go b/internal/frontend/grpc/service.go new file mode 100644 index 00000000..cd4df72c --- /dev/null +++ b/internal/frontend/grpc/service.go @@ -0,0 +1,329 @@ +// Copyright (c) 2022 Proton AG +// +// This file is part of Proton Mail Bridge.Bridge. +// +// Proton Mail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Proton Mail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Proton Mail Bridge. If not, see . + +package grpc + +//go:generate protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative bridge.proto + +import ( + "crypto/tls" + "net" + "runtime" + "strings" + "sync" + "time" + + "github.com/ProtonMail/proton-bridge/v2/internal/bridge" + "github.com/ProtonMail/proton-bridge/v2/internal/config/settings" + "github.com/ProtonMail/proton-bridge/v2/internal/config/useragent" + "github.com/ProtonMail/proton-bridge/v2/internal/events" + "github.com/ProtonMail/proton-bridge/v2/internal/frontend/types" + "github.com/ProtonMail/proton-bridge/v2/internal/locations" + "github.com/ProtonMail/proton-bridge/v2/internal/updater" + "github.com/ProtonMail/proton-bridge/v2/internal/users" + "github.com/ProtonMail/proton-bridge/v2/pkg/keychain" + "github.com/ProtonMail/proton-bridge/v2/pkg/listener" + "github.com/ProtonMail/proton-bridge/v2/pkg/pmapi" + "github.com/sirupsen/logrus" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" +) + +// Service is the RPC service struct. +type Service struct { // nolint:structcheck + UnimplementedBridgeServer + grpcServer *grpc.Server // the gGRPC server + listener net.Listener + eventStreamCh chan *StreamEvent + eventStreamDoneCh chan struct{} + + programName string + programVersion string + panicHandler types.PanicHandler + locations *locations.Locations + settings *settings.Settings + eventListener listener.Listener + updater types.Updater + userAgent *useragent.UserAgent + bridge types.Bridger + restarter types.Restarter + showOnStartup bool + authClient pmapi.Client + auth *pmapi.Auth + password []byte + // newVersionInfo updater.VersionInfo // TO-DO GODT-1670 Implement version check + log *logrus.Entry + initializing sync.WaitGroup + initializationDone sync.Once + firstTimeAutostart sync.Once +} + +// NewService returns a new instance of the service. +func NewService( + version, + programName string, + showOnStartup bool, + panicHandler types.PanicHandler, + locations *locations.Locations, + settings *settings.Settings, + eventListener listener.Listener, + updater types.Updater, + userAgent *useragent.UserAgent, + bridge types.Bridger, + _ types.NoEncConfirmator, + restarter types.Restarter, + +) *Service { + s := Service{ + UnimplementedBridgeServer: UnimplementedBridgeServer{}, + programName: programName, + programVersion: version, + panicHandler: panicHandler, + locations: locations, + settings: settings, + eventListener: eventListener, + updater: updater, + userAgent: userAgent, + bridge: bridge, + restarter: restarter, + showOnStartup: showOnStartup, + + log: logrus.WithField("pkg", "grpc"), + initializing: sync.WaitGroup{}, + initializationDone: sync.Once{}, + firstTimeAutostart: sync.Once{}, + } + + s.userAgent.SetPlatform(runtime.GOOS) // TO-DO GODT-1672 In the previous Qt frontend, this routine used QSysInfo::PrettyProductName to return a more accurate description, e.g. "Windows 10" or "MacOS 10.12" + + cert, err := tls.X509KeyPair([]byte(serverCert), []byte(serverKey)) + if err != nil { + s.log.WithError(err).Error("could not create key pair") + panic(err) + } + + s.initAutostart() + + s.grpcServer = grpc.NewServer(grpc.Creds(credentials.NewTLS(&tls.Config{ + Certificates: []tls.Certificate{cert}, + MinVersion: tls.VersionTLS13, + }))) + + RegisterBridgeServer(s.grpcServer, &s) + + s.listener, err = net.Listen("tcp", "127.0.0.1:9292") // Port should be configurable from the command-line. + if err != nil { + s.log.WithError(err).Error("could not create listener") + panic(err) + } + + return &s +} + +func (s *Service) initAutostart() { + // GODT-1507 Windows: autostart needs to be created after Qt is initialized. + // GODT-1206: if preferences file says it should be on enable it here. + + // TO-DO GODT-1681 Autostart needs to be properly implement for gRPC approach. + + s.firstTimeAutostart.Do(func() { + shouldAutostartBeOn := s.settings.GetBool(settings.AutostartKey) + if s.bridge.IsFirstStart() || shouldAutostartBeOn { + if err := s.bridge.EnableAutostart(); err != nil { + s.log.WithField("prefs", shouldAutostartBeOn).WithError(err).Error("Failed to enable first autostart") + } + return + } + }) +} + +func (s *Service) Loop() error { + defer func() { + s.settings.SetBool(settings.FirstStartGUIKey, false) + }() + + go func() { + defer s.panicHandler.HandlePanic() + s.watchEvents() + }() + + err := s.grpcServer.Serve(s.listener) + if err != nil { + s.log.WithError(err).Error("error serving RPC") + return err + } + return nil +} + +// frontend interface functions TODO GODT-1670 Implement + +func (s *Service) NotifyManualUpdate( /* update */ _ updater.VersionInfo /*canInstall */, _ bool) {} +func (s *Service) SetVersion( /* update */ updater.VersionInfo) {} +func (s *Service) NotifySilentUpdateInstalled() {} +func (s *Service) NotifySilentUpdateError(error) {} +func (s *Service) WaitUntilFrontendIsReady() {} + +func (s *Service) watchEvents() { // nolint:funlen + if s.bridge.HasError(bridge.ErrLocalCacheUnavailable) { + _ = s.SendEvent(NewCacheErrorEvent(CacheErrorType_CACHE_UNAVAILABLE_ERROR)) + } + + errorCh := s.eventListener.ProvideChannel(events.ErrorEvent) + credentialsErrorCh := s.eventListener.ProvideChannel(events.CredentialsErrorEvent) + noActiveKeyForRecipientCh := s.eventListener.ProvideChannel(events.NoActiveKeyForRecipientEvent) + internetConnChangedCh := s.eventListener.ProvideChannel(events.InternetConnChangedEvent) + secondInstanceCh := s.eventListener.ProvideChannel(events.SecondInstanceEvent) + restartBridgeCh := s.eventListener.ProvideChannel(events.RestartBridgeEvent) + addressChangedCh := s.eventListener.ProvideChannel(events.AddressChangedEvent) + addressChangedLogoutCh := s.eventListener.ProvideChannel(events.AddressChangedLogoutEvent) + logoutCh := s.eventListener.ProvideChannel(events.LogoutEvent) + updateApplicationCh := s.eventListener.ProvideChannel(events.UpgradeApplicationEvent) + userChangedCh := s.eventListener.ProvideChannel(events.UserRefreshEvent) + certIssue := s.eventListener.ProvideChannel(events.TLSCertIssue) + + // we forward events to the GUI/frontend via the gRPC event stream. + for { + select { + case errorDetails := <-errorCh: + if strings.Contains(errorDetails, "IMAP failed") { + _ = s.SendEvent(NewMailSettingsErrorEvent(MailSettingsErrorType_IMAP_PORT_ISSUE)) + } + if strings.Contains(errorDetails, "SMTP failed") { + _ = s.SendEvent(NewMailSettingsErrorEvent(MailSettingsErrorType_SMTP_PORT_ISSUE)) + } + case reason := <-credentialsErrorCh: + if reason == keychain.ErrMacKeychainRebuild.Error() { + _ = s.SendEvent(NewKeychainRebuildKeychainEvent()) + continue + } + _ = s.SendEvent(NewKeychainHasNoKeychainEvent()) + case email := <-noActiveKeyForRecipientCh: + _ = s.SendEvent(NewMailNoActiveKeyForRecipientEvent(email)) + case stat := <-internetConnChangedCh: + if stat == events.InternetOff { + _ = s.SendEvent(NewInternetStatusEvent(false)) + } + if stat == events.InternetOn { + _ = s.SendEvent(NewInternetStatusEvent(true)) + } + + case <-secondInstanceCh: + _ = s.SendEvent(NewShowMainWindowEvent()) + case <-restartBridgeCh: + s.restart() + case address := <-addressChangedCh: + _ = s.SendEvent(NewMailAddressChangeEvent(address)) + case address := <-addressChangedLogoutCh: + _ = s.SendEvent(NewMailAddressChangeLogoutEvent(address)) + case userID := <-logoutCh: + user, err := s.bridge.GetUser(userID) + if err != nil { + return + } + _ = s.SendEvent(NewUserDisconnectedEvent(user.Username())) + case <-updateApplicationCh: + s.updateForce() + case userID := <-userChangedCh: + _ = s.SendEvent(NewUserChangedEvent(userID)) + case <-certIssue: + _ = s.SendEvent(NewMailApiCertIssue()) + } + } +} + +func (s *Service) loginAbort() { + s.loginClean() +} + +func (s *Service) loginClean() { + s.auth = nil + s.authClient = nil + for i := range s.password { + s.password[i] = '\x00' + } + s.password = s.password[0:0] +} + +func (s *Service) finishLogin() { + defer s.loginClean() + + if len(s.password) == 0 || s.auth == nil || s.authClient == nil { + s.log. + WithField("hasPass", len(s.password) != 0). + WithField("hasAuth", s.auth != nil). + WithField("hasClient", s.authClient != nil). + Error("Finish login: authentication incomplete") + + _ = s.SendEvent(NewLoginError(LoginErrorType_TWO_PASSWORDS_ABORT, "Missing authentication, try again.")) + return + } + + done := make(chan string) + s.eventListener.Add(events.UserChangeDone, done) + defer s.eventListener.Remove(events.UserChangeDone, done) + + user, err := s.bridge.FinishLogin(s.authClient, s.auth, s.password) + + if err != nil && err != users.ErrUserAlreadyConnected { + s.log.WithError(err).Errorf("Finish login failed") + _ = s.SendEvent(NewLoginError(LoginErrorType_TWO_PASSWORDS_ABORT, err.Error())) + return + } + + // The user changed should be triggered by FinishLogin, but it is not + // guaranteed when this is going to happen. Therefor we should wait + // until we receive the signal from userChanged function. + s.waitForUserChangeDone(done, user.ID()) + + s.log.WithField("userID", user.ID()).Debug("Login finished") + _ = s.SendEvent(NewLoginFinishedEvent(user.ID())) + + if err == users.ErrUserAlreadyConnected { + s.log.WithError(err).Error("User already logged in") + _ = s.SendEvent(NewLoginAlreadyLoggedInEvent(user.ID())) + } +} + +func (s *Service) waitForUserChangeDone(done <-chan string, userID string) { + for { + select { + case changedID := <-done: + if changedID == userID { + return + } + case <-time.After(2 * time.Second): + s.log.WithField("ID", userID).Warning("Login finished but user not added within 2 seconds") + return + } + } +} + +func (s *Service) restart() { + s.log.Error("Restart is not implemented") // TO-DO GODT-1671 implement restart. +} + +func (s *Service) checkUpdate() { + s.log.Error("checkUpdate is not implemented") // TO-DO GODT-1670 implement update check. +} + +func (s *Service) updateForce() { + s.log.Error("updateForce is not implemented") // TO-DO GODT-1670 implement update. +} + +func (s *Service) checkUpdateAndNotify() { + s.log.Error("checkUpdateAndNotify is not implemented") // TO-DO GODT-1670 implement update check. +} diff --git a/internal/frontend/grpc/service_methods.go b/internal/frontend/grpc/service_methods.go new file mode 100644 index 00000000..8934a1f8 --- /dev/null +++ b/internal/frontend/grpc/service_methods.go @@ -0,0 +1,543 @@ +// Copyright (c) 2022 Proton AG +// +// This file is part of Proton Mail Bridge.Bridge. +// +// Proton Mail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Proton Mail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Proton Mail Bridge. If not, see . + +package grpc + +import ( + "context" + "encoding/base64" + "runtime" + + "github.com/Masterminds/semver/v3" + "github.com/ProtonMail/proton-bridge/pkg/ports" + "github.com/ProtonMail/proton-bridge/v2/internal/bridge" + "github.com/ProtonMail/proton-bridge/v2/internal/config/settings" + "github.com/ProtonMail/proton-bridge/v2/internal/frontend/theme" + "github.com/ProtonMail/proton-bridge/v2/internal/updater" + "github.com/ProtonMail/proton-bridge/v2/pkg/keychain" + "github.com/ProtonMail/proton-bridge/v2/pkg/pmapi" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/types/known/emptypb" + "google.golang.org/protobuf/types/known/wrapperspb" +) + +var ErrNotImplemented = status.Errorf(codes.Unimplemented, "Not implemented") + +// GuiReady implement the GuiReady gRPC service call. +func (s *Service) GuiReady(context.Context, *emptypb.Empty) (*emptypb.Empty, error) { + s.log.Info("GuiReady") + // Note nothing to be done. old Qt frontend had a sync.one + return &emptypb.Empty{}, nil +} + +// Quit implement the Quit gRPC service call. +func (s *Service) Quit(ctx context.Context, empty *emptypb.Empty) (*emptypb.Empty, error) { + s.log.Info("Quit") + var err error + if s.eventStreamCh != nil { + if _, err = s.StopEventStream(ctx, empty); err != nil { + s.log.WithError(err).Error("Quit failed.") + } + } + + // The following call is launched as a goroutine, as it will wait for current calls to end, including this one. + go func() { s.grpcServer.GracefulStop() }() + + return &emptypb.Empty{}, err +} + +// Restart implement the Restart gRPC service call. +func (s *Service) Restart(context.Context, *emptypb.Empty) (*emptypb.Empty, error) { + s.log.Info("Restart") // TO-DO-GODT-1671 handle restart. + + s.restart() + + return nil, ErrNotImplemented +} + +func (s *Service) ShowOnStartup(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) { + s.log.Info("ShowOnStartup") + + return wrapperspb.Bool(s.showOnStartup), nil +} + +func (s *Service) ShowSplashScreen(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) { + s.log.Info("ShowSplashScreen") + + if s.bridge.IsFirstStart() { + return wrapperspb.Bool(false), nil + } + + ver, err := semver.NewVersion(s.bridge.GetLastVersion()) + if err != nil { + s.log.WithError(err).WithField("last", s.bridge.GetLastVersion()).Debug("Cannot parse last version") + return wrapperspb.Bool(false), nil + } + + // Current splash screen contains update on rebranding. Therefore, it + // should be shown only if the last used version was less than 2.2.0. + return wrapperspb.Bool(ver.LessThan(semver.MustParse("2.2.0"))), nil +} + +func (s *Service) IsFirstGuiStart(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) { + s.log.Info("IsFirstGuiStart") + + return wrapperspb.Bool(s.settings.GetBool(settings.FirstStartGUIKey)), nil +} + +func (s *Service) SetIsAutostartOn(_ context.Context, isOn *wrapperspb.BoolValue) (*emptypb.Empty, error) { + s.log.WithField("show", isOn.Value).Info("SetIsAutostartOn") + + defer func() { _ = s.SendEvent(NewToggleAutostartFinishedEvent()) }() + + if isOn.Value == s.bridge.IsAutostartEnabled() { + s.initAutostart() + return &emptypb.Empty{}, nil + } + + var err error + if isOn.Value { + err = s.bridge.EnableAutostart() + } else { + err = s.bridge.DisableAutostart() + } + + s.initAutostart() + + if err != nil { + s.log.WithField("makeItEnabled", isOn.Value).WithError(err).Error("Autostart change failed") + } + + return &emptypb.Empty{}, nil +} + +func (s *Service) IsAutostartOn(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) { + s.log.Info("IsAutostartOn") + + return wrapperspb.Bool(s.bridge.IsAutostartEnabled()), nil +} + +func (s *Service) SetIsBetaEnabled(_ context.Context, isEnabled *wrapperspb.BoolValue) (*emptypb.Empty, error) { + s.log.WithField("isEnabled", isEnabled.Value).Info("SetIsBetaEnabled") + + channel := updater.StableChannel + if isEnabled.Value { + channel = updater.EarlyChannel + } + + s.bridge.SetUpdateChannel(channel) + s.checkUpdate() + + return &emptypb.Empty{}, nil +} + +func (s *Service) IsBetaEnabled(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) { + s.log.Info("IsBetaEnabled") + + return wrapperspb.Bool(s.bridge.GetUpdateChannel() == updater.EarlyChannel), nil +} + +func (s *Service) GoOs(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) { + s.log.Info("GoOs") // TO-DO We can probably get rid of this and use QSysInfo::product name + return wrapperspb.String(runtime.GOOS), nil +} + +func (s *Service) TriggerReset(context.Context, *emptypb.Empty) (*emptypb.Empty, error) { + s.log.Info("TriggerReset") + return nil, ErrNotImplemented +} + +func (s *Service) Version(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) { + s.log.Info("Version") + return nil, ErrNotImplemented +} + +func (s *Service) LogsPath(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) { + s.log.Info("LogsPath") + path, err := s.locations.ProvideLogsPath() + if err != nil { + s.log.WithError(err).Error("Cannot determine logs path") + return nil, err + } + return wrapperspb.String(path), nil +} + +func (s *Service) LicensePath(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) { + s.log.Info("LicensePath") + return wrapperspb.String(s.locations.GetLicenseFilePath()), nil +} + +func (s *Service) DependencyLicensesLink(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) { + return wrapperspb.String(s.locations.GetDependencyLicensesLink()), nil +} + +func (s *Service) SetColorSchemeName(_ context.Context, name *wrapperspb.StringValue) (*emptypb.Empty, error) { + s.log.WithField("ColorSchemeName", name.Value).Info("SetColorSchemeName") + + if !theme.IsAvailable(theme.Theme(name.Value)) { + s.log.WithField("scheme", name.Value).Warn("Color scheme not available") + return nil, status.Error(codes.NotFound, "Color scheme not available") + } + + s.settings.Set(settings.ColorScheme, name.Value) + + return &emptypb.Empty{}, nil +} + +func (s *Service) ColorSchemeName(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) { + s.log.Info("ColorSchemeName") + + current := s.settings.Get(settings.ColorScheme) + if !theme.IsAvailable(theme.Theme(current)) { + current = string(theme.DefaultTheme()) + s.settings.Set(settings.ColorScheme, current) + } + + return wrapperspb.String(current), nil +} + +func (s *Service) CurrentEmailClient(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) { + s.log.Info("CurrentEmailClient") + + return wrapperspb.String(s.userAgent.String()), nil +} + +func (s *Service) ReportBug(_ context.Context, report *ReportBugRequest) (*emptypb.Empty, error) { + s.log.WithField("description", report.Description). + WithField("address", report.Address). + WithField("emailClient", report.EmailClient). + WithField("includeLogs", report.IncludeLogs). + Info("ReportBug") + return &emptypb.Empty{}, nil +} + +func (s *Service) Login(_ context.Context, login *LoginRequest) (*emptypb.Empty, error) { + s.log.WithField("username", login.Username).Info("Login") + go func() { + defer s.panicHandler.HandlePanic() + + var err error + s.password, err = base64.StdEncoding.DecodeString(login.Password) + if err != nil { + s.log.WithError(err).Error("Cannot decode password") + _ = s.SendEvent(NewLoginError(LoginErrorType_USERNAME_PASSWORD_ERROR, "Cannot decode password")) + s.loginClean() + return + } + + s.authClient, s.auth, err = s.bridge.Login(login.Username, s.password) + if err != nil { + if err == pmapi.ErrPasswordWrong { + // Remove error message since it is hardcoded in QML. + _ = s.SendEvent(NewLoginError(LoginErrorType_USERNAME_PASSWORD_ERROR, "")) + s.loginClean() + return + } + if err == pmapi.ErrPaidPlanRequired { + _ = s.SendEvent(NewLoginError(LoginErrorType_FREE_USER, "")) + s.loginClean() + return + } + _ = s.SendEvent(NewLoginError(LoginErrorType_USERNAME_PASSWORD_ERROR, err.Error())) + s.loginClean() + return + } + + if s.auth.HasTwoFactor() { + _ = s.SendEvent(NewLoginTfaRequestedEvent(login.Username)) + return + } + if s.auth.HasMailboxPassword() { + _ = s.SendEvent(NewLoginTwoPasswordsRequestedEvent()) + return + } + + s.finishLogin() + }() + return &emptypb.Empty{}, nil +} + +func (s *Service) Login2FA(_ context.Context, login *LoginRequest) (*emptypb.Empty, error) { + s.log.WithField("username", login.Username).Info("Login2FA") + + go func() { + defer s.panicHandler.HandlePanic() + + if s.auth == nil || s.authClient == nil { + s.log.Errorf("Login 2FA: authethication incomplete %p %p", s.auth, s.authClient) + _ = s.SendEvent(NewLoginError(LoginErrorType_TFA_ABORT, "Missing authentication, try again.")) + s.loginClean() + return + } + + twoFA, err := base64.StdEncoding.DecodeString(login.Password) + if err != nil { + s.log.WithError(err).Error("Cannot decode 2fa code") + _ = s.SendEvent(NewLoginError(LoginErrorType_USERNAME_PASSWORD_ERROR, "Cannot decode 2fa code")) + s.loginClean() + return + } + + err = s.authClient.Auth2FA(context.Background(), string(twoFA)) + if err == pmapi.ErrBad2FACodeTryAgain { + s.log.Warn("Login 2FA: retry 2fa") + _ = s.SendEvent(NewLoginError(LoginErrorType_TFA_ERROR, "")) + return + } + + if err == pmapi.ErrBad2FACode { + s.log.Warn("Login 2FA: abort 2fa") + _ = s.SendEvent(NewLoginError(LoginErrorType_TFA_ABORT, "")) + s.loginClean() + return + } + + if err != nil { + s.log.WithError(err).Warn("Login 2FA: failed.") + _ = s.SendEvent(NewLoginError(LoginErrorType_TFA_ABORT, err.Error())) + s.loginClean() + return + } + + if s.auth.HasMailboxPassword() { + _ = s.SendEvent(NewLoginTwoPasswordsRequestedEvent()) + return + } + + s.finishLogin() + }() + + return &emptypb.Empty{}, nil +} + +func (s *Service) Login2Passwords(_ context.Context, login *LoginRequest) (*emptypb.Empty, error) { + s.log.WithField("username", login.Username).Info("Login2Passwords") + + go func() { + defer s.panicHandler.HandlePanic() + + var err error + s.password, err = base64.StdEncoding.DecodeString(login.Password) + + if err != nil { + s.log.WithError(err).Error("Cannot decode mbox password") + _ = s.SendEvent(NewLoginError(LoginErrorType_USERNAME_PASSWORD_ERROR, "Cannot decode mbox password")) + s.loginClean() + return + } + + s.finishLogin() + }() + + return &emptypb.Empty{}, nil +} + +func (s *Service) LoginAbort(_ context.Context, loginAbort *LoginAbortRequest) (*emptypb.Empty, error) { + s.log.WithField("username", loginAbort.Username).Info("LoginAbort") + go func() { + defer s.panicHandler.HandlePanic() + + s.loginAbort() + }() + + return &emptypb.Empty{}, nil +} + +func (s *Service) CheckUpdate(context.Context, *emptypb.Empty) (*emptypb.Empty, error) { + s.log.Info("CheckUpdate") + // TO-DO GODT-1670 Implement update check + return &emptypb.Empty{}, nil +} + +func (s *Service) InstallUpdate(context.Context, *emptypb.Empty) (*emptypb.Empty, error) { + s.log.Info("InstallUpdate") + // TO-DO GODT-1670 Implement update install + return &emptypb.Empty{}, nil +} + +func (s *Service) SetIsAutomaticUpdateOn(_ context.Context, isOn *wrapperspb.BoolValue) (*emptypb.Empty, error) { + s.log.WithField("isOn", isOn.Value).Info("SetIsAutomaticUpdateOn") + + currentlyOn := s.settings.GetBool(settings.AutoUpdateKey) + if currentlyOn == isOn.Value { + return &emptypb.Empty{}, nil + } + + s.settings.SetBool(settings.AutoUpdateKey, isOn.Value) + s.checkUpdateAndNotify() + + return &emptypb.Empty{}, nil +} + +func (s *Service) IsAutomaticUpdateOn(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) { + s.log.Info("IsAutomaticUpdateOn") + + return wrapperspb.Bool(s.settings.GetBool(settings.AutoUpdateKey)), nil +} + +func (s *Service) IsCacheOnDiskEnabled(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) { + s.log.Info("IsCacheOnDiskEnabled") + return wrapperspb.Bool(s.settings.GetBool(settings.CacheEnabledKey)), nil +} + +func (s *Service) DiskCachePath(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) { + s.log.Info("DiskCachePath") + return wrapperspb.String(s.settings.Get(settings.CacheLocationKey)), nil +} + +func (s *Service) ChangeLocalCache(_ context.Context, change *ChangeLocalCacheRequest) (*emptypb.Empty, error) { + s.log.WithField("enableDiskCache", change.EnableDiskCache). + WithField("diskCachePath", change.DiskCachePath). + Info("DiskCachePath") + + defer func() { _ = s.SendEvent(NewCacheChangeLocalCacheFinishedEvent()) }() + defer func() { _ = s.SendEvent(NewIsCacheOnDiskEnabledChanged(s.settings.GetBool(settings.CacheEnabledKey))) }() + defer func() { _ = s.SendEvent(NewDiskCachePathChanged(s.settings.Get(settings.CacheCompressionKey))) }() + + if change.EnableDiskCache != s.settings.GetBool(settings.CacheEnabledKey) { + if change.EnableDiskCache { + if err := s.bridge.EnableCache(); err != nil { + s.log.WithError(err).Error("Cannot enable disk cache") + } + } else { + if err := s.bridge.DisableCache(); err != nil { + s.log.WithError(err).Error("Cannot disable disk cache") + } + } + } + + path := change.DiskCachePath + //goland:noinspection GoBoolExpressions + if (runtime.GOOS == "windows") && (path[0] == '/') { + path = path[1:] + } + + if change.EnableDiskCache && path != s.settings.Get(settings.CacheLocationKey) { + if err := s.bridge.MigrateCache(s.settings.Get(settings.CacheLocationKey), path); err != nil { + s.log.WithError(err).Error("The local cache location could not be changed.") + _ = s.SendEvent(NewCacheErrorEvent(CacheErrorType_CACHE_CANT_MOVE_ERROR)) + return &emptypb.Empty{}, nil + } + s.settings.Set(settings.CacheLocationKey, path) + } + + _ = s.SendEvent(NewCacheLocationChangeSuccessEvent()) + s.restart() + + return &emptypb.Empty{}, nil +} + +func (s *Service) SetIsDoHEnabled(_ context.Context, isEnabled *wrapperspb.BoolValue) (*emptypb.Empty, error) { + s.log.WithField("isEnabled", isEnabled.Value).Info("SetIsDohEnabled") + + s.bridge.SetProxyAllowed(isEnabled.Value) + + return &emptypb.Empty{}, nil +} + +func (s *Service) IsDoHEnabled(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) { + s.log.Info("IsDohEnabled") + + return wrapperspb.Bool(s.bridge.GetProxyAllowed()), nil +} + +func (s *Service) SetUseSslForSmtp(_ context.Context, useSsl *wrapperspb.BoolValue) (*emptypb.Empty, error) { //nolint:revive,stylecheck + s.log.WithField("useSsl", useSsl.Value).Info("SetUseSslForSmtp") + + if s.settings.GetBool(settings.SMTPSSLKey) == useSsl.Value { + return &emptypb.Empty{}, nil + } + + defer func() { _ = s.SendEvent(NewMailSettingsUseSslForSmtpFinishedEvent()) }() + + s.settings.SetBool(settings.SMTPSSLKey, useSsl.Value) + s.restart() + + return &emptypb.Empty{}, nil +} + +func (s *Service) UseSslForSmtp(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) { //nolint:revive,stylecheck + s.log.Info("UseSslForSmtp") + + return wrapperspb.Bool(s.settings.GetBool(settings.SMTPSSLKey)), nil +} + +func (s *Service) Hostname(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) { + s.log.Info("Hostname") + + return wrapperspb.String(bridge.Host), nil +} + +func (s *Service) ImapPort(context.Context, *emptypb.Empty) (*wrapperspb.Int32Value, error) { + s.log.Info("ImapPort") + + return wrapperspb.Int32(int32(s.settings.GetInt(settings.IMAPPortKey))), nil +} + +func (s *Service) SmtpPort(context.Context, *emptypb.Empty) (*wrapperspb.Int32Value, error) { //nolint:revive,stylecheck + s.log.Info("SmtpPort") + + return wrapperspb.Int32(int32(s.settings.GetInt(settings.SMTPPortKey))), nil +} + +func (s *Service) ChangePorts(_ context.Context, ports *ChangePortsRequest) (*emptypb.Empty, error) { + s.log.WithField("imapPort", ports.ImapPort).WithField("smtpPort", ports.SmtpPort).Info("ChangePorts") + + defer func() { _ = s.SendEvent(NewMailSettingsChangePortFinishedEvent()) }() + + s.settings.SetInt(settings.IMAPPortKey, int(ports.ImapPort)) + s.settings.SetInt(settings.SMTPPortKey, int(ports.SmtpPort)) + + s.restart() + return &emptypb.Empty{}, nil +} + +func (s *Service) IsPortFree(_ context.Context, port *wrapperspb.Int32Value) (*wrapperspb.BoolValue, error) { + s.log.Info("IsPortFree") + return wrapperspb.Bool(ports.IsPortFree(int(port.Value))), nil +} + +func (s *Service) AvailableKeychains(context.Context, *emptypb.Empty) (*AvailableKeychainsResponse, error) { + s.log.Info("AvailableKeychains") + + keychains := make([]string, 0, len(keychain.Helpers)) + for chain := range keychain.Helpers { + keychains = append(keychains, chain) + } + + return &AvailableKeychainsResponse{Keychains: keychains}, nil +} + +func (s *Service) SetCurrentKeychain(_ context.Context, keychain *wrapperspb.StringValue) (*emptypb.Empty, error) { + s.log.WithField("keychain", keychain.Value).Info("SetCurrentKeyChain") // we do not check validity. + defer func() { _ = s.SendEvent(NewKeychainChangeKeychainFinishedEvent()) }() + + if s.bridge.GetKeychainApp() == keychain.Value { + return &emptypb.Empty{}, nil + } + + s.bridge.SetKeychainApp(keychain.Value) + + return &emptypb.Empty{}, nil +} + +func (s *Service) CurrentKeychain(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) { + s.log.Info("CurrentKeychain") + + return wrapperspb.String(s.bridge.GetKeychainApp()), nil +} diff --git a/internal/frontend/grpc/service_stream.go b/internal/frontend/grpc/service_stream.go new file mode 100644 index 00000000..8df66f13 --- /dev/null +++ b/internal/frontend/grpc/service_stream.go @@ -0,0 +1,151 @@ +// Copyright (c) 2022 Proton AG +// +// This file is part of Proton Mail Bridge.Bridge. +// +// Proton Mail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Proton Mail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Proton Mail Bridge. If not, see . + +package grpc + +import ( + "context" + + "github.com/pkg/errors" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/types/known/emptypb" +) + +// StartEventStream implement the gRPC server->Client event stream. +func (s *Service) StartEventStream(_ *emptypb.Empty, server Bridge_StartEventStreamServer) error { + s.log.Info("Starting Event stream") + + if s.eventStreamCh != nil { + return status.Errorf(codes.AlreadyExists, "the service is already streaming") // TO-DO GODT-1667 decide if we want to kill the existing stream. + } + + s.eventStreamCh = make(chan *StreamEvent) + s.eventStreamDoneCh = make(chan struct{}) + + // TO-DO GODT-1667 We should have a safer we to close this channel? What if an event occur while we are closing? + defer func() { + close(s.eventStreamCh) + s.eventStreamCh = nil + close(s.eventStreamDoneCh) + s.eventStreamDoneCh = nil + }() + + for { + select { + case <-s.eventStreamDoneCh: + s.log.Info("Stop Event stream") + return nil + + case event := <-s.eventStreamCh: + s.log.WithField("event", event).Info("Sending event") + if err := server.Send(event); err != nil { + s.log.Info("Stop Event stream") + return err + } + } + } +} + +// StopEventStream stops the event stream. +func (s *Service) StopEventStream(_ context.Context, _ *emptypb.Empty) (*emptypb.Empty, error) { + if s.eventStreamCh == nil { + return nil, status.Errorf(codes.NotFound, "The service is not streaming") + } + + s.eventStreamDoneCh <- struct{}{} + + return &emptypb.Empty{}, nil +} + +// SendEvent sends an event to the via the gRPC event stream. +func (s *Service) SendEvent(event *StreamEvent) error { + if s.eventStreamCh == nil { + return errors.New("gRPC service is not streaming") + } + + s.eventStreamCh <- event + + return nil +} + +// StartEventTest sends all the known event via gRPC. +func (s *Service) StartEventTest() error { //nolint:funlen + const dummyAddress = "dummy@proton.me" + events := []*StreamEvent{ + // app + NewInternetStatusEvent(true), + NewToggleAutostartFinishedEvent(), + NewResetFinishedEvent(), + NewReportBugFinishedEvent(), + NewReportBugSuccessEvent(), + NewReportBugErrorEvent(), + NewShowMainWindowEvent(), + + // login + NewLoginError(LoginErrorType_FREE_USER, "error"), + NewLoginTfaRequestedEvent(dummyAddress), + NewLoginTwoPasswordsRequestedEvent(), + NewLoginFinishedEvent("userID"), + NewLoginAlreadyLoggedInEvent("userID"), + + // update + NewUpdateErrorEvent(UpdateErrorType_UPDATE_SILENT_ERROR), + NewUpdateManualReadyEvent("2.0"), + NewUpdateManualRestartNeededEvent(), + NewUpdateForceEvent("2.0"), + NewUpdateSilentRestartNeededEvent(), + NewUpdateIsLatestVersionEvent(), + NewUpdateCheckFinishedEvent(), + + // cache + NewCacheErrorEvent(CacheErrorType_CACHE_UNAVAILABLE_ERROR), + NewCacheLocationChangeSuccessEvent(), + NewCacheChangeLocalCacheFinishedEvent(), + NewIsCacheOnDiskEnabledChanged(true), + NewDiskCachePathChanged("/dummy/path"), + + // mail settings + NewMailSettingsErrorEvent(MailSettingsErrorType_IMAP_PORT_ISSUE), + NewMailSettingsUseSslForSmtpFinishedEvent(), + NewMailSettingsChangePortFinishedEvent(), + + // keychain + NewKeychainChangeKeychainFinishedEvent(), + NewKeychainHasNoKeychainEvent(), + NewKeychainRebuildKeychainEvent(), + + // mail + NewMailNoActiveKeyForRecipientEvent(dummyAddress), + NewMailAddressChangeEvent(dummyAddress), + NewMailAddressChangeLogoutEvent(dummyAddress), + NewMailApiCertIssue(), + + // user + NewUserToggleSplitModeFinishedEvent("userID"), + NewUserDisconnectedEvent("username"), + NewUserChangedEvent("userID"), + } + + for _, event := range events { + if err := s.SendEvent(event); err != nil { + return err + } + } + + return nil +} diff --git a/internal/frontend/grpc/service_user.go b/internal/frontend/grpc/service_user.go new file mode 100644 index 00000000..f5e73c92 --- /dev/null +++ b/internal/frontend/grpc/service_user.go @@ -0,0 +1,132 @@ +// Copyright (c) 2022 Proton AG +// +// This file is part of Proton Mail Bridge. +// +// Proton Mail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Proton Mail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Proton Mail Bridge. If not, see . + +package grpc + +import ( + "context" + "time" + + "github.com/ProtonMail/proton-bridge/v2/internal/frontend/clientconfig" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/types/known/emptypb" + "google.golang.org/protobuf/types/known/wrapperspb" +) + +func (s *Service) GetUserList(context.Context, *emptypb.Empty) (*UserListResponse, error) { + s.log.Info("GetUserList") + + users := s.bridge.GetUsers() + + userList := make([]*User, len(users)) + for i, user := range users { + userList[i] = grpcUserFromBridge(user) + } + + // If there are no active accounts. + if len(userList) == 0 { + s.log.Info("No active accounts") + } + + return &UserListResponse{Users: userList}, nil +} + +func (s *Service) GetUser(_ context.Context, userID *wrapperspb.StringValue) (*User, error) { + s.log.WithField("userID", userID).Info("GetUser") + + user, err := s.bridge.GetUser(userID.Value) + if err != nil { + return nil, status.Errorf(codes.NotFound, "user not found %v", userID.Value) + } + + return grpcUserFromBridge(user), nil +} + +func (s *Service) SetUserSplitMode(_ context.Context, splitMode *UserSplitModeRequest) (*emptypb.Empty, error) { + s.log.WithField("UserID", splitMode.UserID).WithField("Active", splitMode.Active).Info("SetUserSplitMode") + + user, err := s.bridge.GetUser(splitMode.UserID) + if err != nil { + return nil, status.Errorf(codes.NotFound, "user not found %v", splitMode.UserID) + } + + go func() { + defer s.panicHandler.HandlePanic() + defer func() { _ = s.SendEvent(NewUserToggleSplitModeFinishedEvent(splitMode.UserID)) }() + if splitMode.Active == user.IsCombinedAddressMode() { + _ = user.SwitchAddressMode() // check for errors + } + }() + + return &emptypb.Empty{}, nil +} + +func (s *Service) LogoutUser(_ context.Context, userID *wrapperspb.StringValue) (*emptypb.Empty, error) { + s.log.WithField("UserID", userID.Value).Info("LogoutUser") + + user, err := s.bridge.GetUser(userID.Value) + if err != nil { + return nil, status.Errorf(codes.NotFound, "user not found %v", userID.Value) + } + + go func() { + defer s.panicHandler.HandlePanic() + _ = user.Logout() + }() + + return &emptypb.Empty{}, nil +} + +func (s *Service) RemoveUser(_ context.Context, userID *wrapperspb.StringValue) (*emptypb.Empty, error) { + s.log.WithField("UserID", userID.Value).Info("RemoveUser") + + go func() { + defer s.panicHandler.HandlePanic() + + // remove preferences + if err := s.bridge.DeleteUser(userID.Value, false); err != nil { + s.log.WithError(err).Error("Failed to remove user") + // notification + } + }() + return &emptypb.Empty{}, nil +} + +func (s *Service) ConfigureUserAppleMail(_ context.Context, request *ConfigureAppleMailRequest) (*emptypb.Empty, error) { + s.log.WithField("UserID", request.UserID).WithField("Address", request.Address).Info("ConfigureUserAppleMail") + + user, err := s.bridge.GetUser(request.UserID) + if err != nil { + s.log.WithField("userID", request.UserID).Error("Cannot configure AppleMail for user") + return nil, status.Error(codes.NotFound, "Cannot configure AppleMail for user") + } + + needRestart, err := clientconfig.ConfigureAppleMail(user, request.Address, s.settings) + if err != nil { + s.log.WithError(err).Error("Apple Mail config failed") + return nil, status.Error(codes.Internal, "Apple Mail config failed") + } + + if needRestart { + // There is delay needed for external window to open + time.Sleep(2 * time.Second) + s.restart() + } + + return &emptypb.Empty{}, nil +} diff --git a/internal/frontend/qt/helpers.go b/internal/frontend/grpc/utils.go similarity index 70% rename from internal/frontend/qt/helpers.go rename to internal/frontend/grpc/utils.go index 25a56dbb..027bd839 100644 --- a/internal/frontend/qt/helpers.go +++ b/internal/frontend/grpc/utils.go @@ -15,29 +15,15 @@ // You should have received a copy of the GNU General Public License // along with Proton Mail Bridge. If not, see . -//go:build build_qt -// +build build_qt - -package qt +package grpc import ( "regexp" "strings" - "github.com/therecipe/qt/core" - "github.com/therecipe/qt/gui" + "github.com/ProtonMail/proton-bridge/v2/internal/frontend/types" ) -// getCursorPos returns current mouse position to be able to use in QML -func getCursorPos() *core.QPoint { - return gui.QCursor_Pos() -} - -// newQByteArrayFromString is a wrapper for new QByteArray from string. -func newQByteArrayFromString(name string) *core.QByteArray { - return core.NewQByteArray2(name, len(name)) -} - var ( reMultiSpaces = regexp.MustCompile(`\s{2,}`) reStartWithSymbol = regexp.MustCompile(`^[.,/#!$@%^&*;:{}=\-_` + "`" + `~()]`) @@ -69,3 +55,19 @@ func getInitials(fullName string) string { } return strings.ToUpper(initials) } + +// grpcUserFromBridge converts a bridge user to a gRPC user. +func grpcUserFromBridge(user types.User) *User { + return &User{ + Id: user.ID(), + Username: user.Username(), + AvatarText: getInitials(user.Username()), + LoggedIn: user.IsConnected(), + SplitMode: user.IsCombinedAddressMode(), + SetupGuideSeen: true, // users listed have already seen the setup guide. + UsedBytes: user.UsedBytes(), + TotalBytes: user.TotalBytes(), + Password: user.GetBridgePassword(), + Addresses: user.GetAddresses(), + } +} diff --git a/internal/frontend/qt/frontend.go b/internal/frontend/qt/frontend.go deleted file mode 100644 index 707c399b..00000000 --- a/internal/frontend/qt/frontend.go +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright (c) 2022 Proton AG -// -// This file is part of Proton Mail Bridge. -// -// Proton Mail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Proton Mail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Proton Mail Bridge. If not, see . - -//go:build build_qt -// +build build_qt - -// Package qt provides communication between Qt/QML frontend and Go backend -package qt - -import ( - "fmt" - "sync" - - "github.com/ProtonMail/proton-bridge/v2/internal/config/settings" - "github.com/ProtonMail/proton-bridge/v2/internal/config/useragent" - "github.com/ProtonMail/proton-bridge/v2/internal/frontend/types" - "github.com/ProtonMail/proton-bridge/v2/internal/locations" - "github.com/ProtonMail/proton-bridge/v2/internal/updater" - "github.com/ProtonMail/proton-bridge/v2/pkg/listener" - "github.com/ProtonMail/proton-bridge/v2/pkg/pmapi" - "github.com/sirupsen/logrus" - "github.com/therecipe/qt/core" - "github.com/therecipe/qt/qml" - "github.com/therecipe/qt/widgets" -) - -type FrontendQt struct { - programName, programVersion string - - panicHandler types.PanicHandler - locations *locations.Locations - settings *settings.Settings - eventListener listener.Listener - updater types.Updater - userAgent *useragent.UserAgent - bridge types.Bridger - noEncConfirmator types.NoEncConfirmator - restarter types.Restarter - showOnStartup bool - - authClient pmapi.Client - auth *pmapi.Auth - password []byte - - newVersionInfo updater.VersionInfo - - log *logrus.Entry - initializing sync.WaitGroup - initializationDone sync.Once - firstTimeAutostart sync.Once - - app *widgets.QApplication - engine *qml.QQmlEngine - qml *QMLBackend -} - -func New( - version, - buildVersion, - programName string, - showWindowOnStart bool, - panicHandler types.PanicHandler, - locations *locations.Locations, - settings *settings.Settings, - eventListener listener.Listener, - updater types.Updater, - userAgent *useragent.UserAgent, - bridge types.Bridger, - _ types.NoEncConfirmator, - restarter types.Restarter, -) *FrontendQt { - userAgent.SetPlatform(core.QSysInfo_PrettyProductName()) - - f := &FrontendQt{ - programName: programName, - programVersion: version, - log: logrus.WithField("pkg", "frontend/qt"), - - panicHandler: panicHandler, - locations: locations, - settings: settings, - eventListener: eventListener, - updater: updater, - userAgent: userAgent, - bridge: bridge, - restarter: restarter, - showOnStartup: showWindowOnStart, - } - - // Initializing.Done is only called sync.Once. Please keep the increment - // set to 1 - f.initializing.Add(1) - - return f -} - -func (f *FrontendQt) Loop() error { - err := f.initiateQtApplication() - if err != nil { - return err - } - - go func() { - defer f.panicHandler.HandlePanic() - f.watchEvents() - }() - - // Set whether this is the first time GUI starts. - f.qml.SetIsFirstGUIStart(f.settings.GetBool(settings.FirstStartGUIKey)) - defer func() { - f.settings.SetBool(settings.FirstStartGUIKey, false) - }() - - if ret := f.app.Exec(); ret != 0 { - err := fmt.Errorf("Event loop ended with return value: %v", ret) - f.log.Warn("App exec", err) - return err - } - - return nil -} - -func (f *FrontendQt) NotifyManualUpdate(version updater.VersionInfo, canInstall bool) { - if canInstall { - f.qml.UpdateManualReady(version.Version.String()) - } else { - f.qml.UpdateManualError() - } -} - -func (f *FrontendQt) SetVersion(version updater.VersionInfo) { - f.newVersionInfo = version - f.qml.SetReleaseNotesLink(core.NewQUrl3(version.ReleaseNotesPage, core.QUrl__TolerantMode)) - f.qml.SetLandingPageLink(core.NewQUrl3(version.LandingPage, core.QUrl__TolerantMode)) -} - -func (f *FrontendQt) NotifySilentUpdateInstalled() { - f.qml.UpdateSilentRestartNeeded() -} - -func (f *FrontendQt) NotifySilentUpdateError(err error) { - f.log.WithError(err).Warn("In-app update failed, asking for manual.") - f.qml.UpdateManualError() -} - -func (f *FrontendQt) WaitUntilFrontendIsReady() { - f.initializing.Wait() -} diff --git a/internal/frontend/qt/frontend_events.go b/internal/frontend/qt/frontend_events.go deleted file mode 100644 index ed95cb64..00000000 --- a/internal/frontend/qt/frontend_events.go +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (c) 2022 Proton AG -// -// This file is part of Proton Mail Bridge. -// -// Proton Mail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Proton Mail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Proton Mail Bridge. If not, see . - -//go:build build_qt -// +build build_qt - -// Package qt provides communication between Qt/QML frontend and Go backend -package qt - -import ( - "strings" - - "github.com/ProtonMail/proton-bridge/v2/internal/bridge" - "github.com/ProtonMail/proton-bridge/v2/internal/events" - "github.com/ProtonMail/proton-bridge/v2/pkg/keychain" -) - -func (f *FrontendQt) watchEvents() { - f.WaitUntilFrontendIsReady() - - // First we check bridge global errors for any error that should be shown on GUI. - if f.bridge.HasError(bridge.ErrLocalCacheUnavailable) { - f.qml.CacheUnavailable() - } - - errorCh := f.eventListener.ProvideChannel(events.ErrorEvent) - credentialsErrorCh := f.eventListener.ProvideChannel(events.CredentialsErrorEvent) - noActiveKeyForRecipientCh := f.eventListener.ProvideChannel(events.NoActiveKeyForRecipientEvent) - internetConnChangedCh := f.eventListener.ProvideChannel(events.InternetConnChangedEvent) - secondInstanceCh := f.eventListener.ProvideChannel(events.SecondInstanceEvent) - restartBridgeCh := f.eventListener.ProvideChannel(events.RestartBridgeEvent) - addressChangedCh := f.eventListener.ProvideChannel(events.AddressChangedEvent) - addressChangedLogoutCh := f.eventListener.ProvideChannel(events.AddressChangedLogoutEvent) - logoutCh := f.eventListener.ProvideChannel(events.LogoutEvent) - updateApplicationCh := f.eventListener.ProvideChannel(events.UpgradeApplicationEvent) - userChangedCh := f.eventListener.ProvideChannel(events.UserRefreshEvent) - certIssue := f.eventListener.ProvideChannel(events.TLSCertIssue) - - // This loop is executed outside main Qt application thread. In order - // to make sure that all signals are propagated correctly to QML we - // must call QMLBackend signals to apply any changes to GUI. The - // signals will make sure the changes are executed in main Qt app - // thread. - for { - select { - case errorDetails := <-errorCh: - if strings.Contains(errorDetails, "IMAP failed") { - f.qml.PortIssueIMAP() - } - if strings.Contains(errorDetails, "SMTP failed") { - f.qml.PortIssueSMTP() - } - case reason := <-credentialsErrorCh: - if reason == keychain.ErrMacKeychainRebuild.Error() { - f.qml.NotifyRebuildKeychain() - continue - } - f.qml.NotifyHasNoKeychain() - case email := <-noActiveKeyForRecipientCh: - f.qml.NoActiveKeyForRecipient(email) - case stat := <-internetConnChangedCh: - if stat == events.InternetOff { - f.qml.InternetOff() - } - if stat == events.InternetOn { - f.qml.InternetOn() - } - case <-secondInstanceCh: - f.qml.ShowMainWindow() - case <-restartBridgeCh: - f.restart() - case address := <-addressChangedCh: - f.qml.AddressChanged(address) - case address := <-addressChangedLogoutCh: - f.qml.AddressChangedLogout(address) - case userID := <-logoutCh: - user, err := f.bridge.GetUser(userID) - if err != nil { - return - } - f.qml.UserDisconnected(user.Username()) - case <-updateApplicationCh: - f.updateForce() - case userID := <-userChangedCh: - f.qml.UserChanged(userID) - case <-certIssue: - f.qml.ApiCertIssue() - } - } -} diff --git a/internal/frontend/qt/frontend_help.go b/internal/frontend/qt/frontend_help.go deleted file mode 100644 index 2145ec6c..00000000 --- a/internal/frontend/qt/frontend_help.go +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) 2022 Proton AG -// -// This file is part of Proton Mail Bridge. -// -// Proton Mail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Proton Mail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Proton Mail Bridge. If not, see . - -//go:build build_qt -// +build build_qt - -package qt - -import ( - "github.com/therecipe/qt/core" -) - -func (f *FrontendQt) setVersion() { - f.qml.SetVersion(f.programVersion) -} - -func (f *FrontendQt) setLogsPath() { - path, err := f.locations.ProvideLogsPath() - if err != nil { - f.log.WithError(err).Error("Cannot update path folder") - return - } - - f.qml.SetLogsPath(core.QUrl_FromLocalFile(path)) -} - -func (f *FrontendQt) setLicensePath() { - f.qml.SetLicensePath(core.QUrl_FromLocalFile(f.locations.GetLicenseFilePath())) - f.qml.SetDependencyLicensesLink(core.NewQUrl3(f.locations.GetDependencyLicensesLink(), core.QUrl__TolerantMode)) -} - -func (f *FrontendQt) setCurrentEmailClient() { - f.qml.SetCurrentEmailClient(f.userAgent.String()) -} - -func (f *FrontendQt) reportBug(description, address, emailClient string, includeLogs bool) { - defer f.qml.ReportBugFinished() - - if err := f.bridge.ReportBug( - core.QSysInfo_ProductType(), - core.QSysInfo_PrettyProductName(), - description, - address, - address, - emailClient, - includeLogs, - ); err != nil { - f.log.WithError(err).Error("Failed to report bug") - f.qml.BugReportSendError() - return - } - - f.qml.BugReportSendSuccess() -} diff --git a/internal/frontend/qt/frontend_init.go b/internal/frontend/qt/frontend_init.go deleted file mode 100644 index 7191f7ae..00000000 --- a/internal/frontend/qt/frontend_init.go +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright (c) 2022 Proton AG -// -// This file is part of Proton Mail Bridge. -// -// Proton Mail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Proton Mail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Proton Mail Bridge. If not, see . - -//go:build build_qt -// +build build_qt - -package qt - -import ( - "errors" - "os" - "runtime" - - "github.com/Masterminds/semver/v3" - qmlLog "github.com/ProtonMail/proton-bridge/v2/internal/frontend/qt/log" - "github.com/therecipe/qt/core" - "github.com/therecipe/qt/qml" - "github.com/therecipe/qt/quickcontrols2" - "github.com/therecipe/qt/widgets" -) - -func (f *FrontendQt) initiateQtApplication() error { - qmlLog.InstallMessageHandler() - - f.app = widgets.NewQApplication(len(os.Args), os.Args) - - if os.Getenv("QSG_INFO") != "" && os.Getenv("QSG_INFO") != "0" { - core.QLoggingCategory_SetFilterRules("qt.scenegraph.general=true") - } - - core.QCoreApplication_SetApplicationName(f.programName) - core.QCoreApplication_SetApplicationVersion(f.programVersion) - core.QCoreApplication_SetOrganizationName("Proton AG") - core.QCoreApplication_SetOrganizationDomain("proton.ch") - - // High DPI scaling for windows. - core.QCoreApplication_SetAttribute(core.Qt__AA_EnableHighDpiScaling, false) - - // Use software OpenGL to avoid dedicated GPU on darwin. It cause no - // problems on linux, but it can cause initializaion issues on windows - // for some specific GPU / driver combination. - if runtime.GOOS != "windows" { - core.QCoreApplication_SetAttribute(core.Qt__AA_UseSoftwareOpenGL, true) - } - - // Bridge runs background, no window is needed to be opened. - f.app.SetQuitOnLastWindowClosed(false) - - // QML Engine and path - f.engine = qml.NewQQmlEngine(f.app) - rootComponent := qml.NewQQmlComponent2(f.engine, f.engine) - - f.qml = NewQMLBackend(f.engine) - f.qml.setup(f) - - f.engine.AddImportPath("qrc:/qml/") - f.engine.AddPluginPath("qrc:/qml/") - - // Add style: if colorScheme / style is forgotten we should fallback to - // default style and should be Proton - quickcontrols2.QQuickStyle_AddStylePath("qrc:/qml/") - quickcontrols2.QQuickStyle_SetStyle("Proton") - - // Before loading a component we should load translations. - // See https://github.com/qt/qtdeclarative/blob/bedef212a74a62452ed31d7f65536a6c67881fc4/src/qml/qml/qqmlapplicationengine.cpp#L69 as example. - - rootComponent.LoadUrl(core.NewQUrl3("qrc:/qml/Bridge.qml", 0)) - - if rootComponent.Status() != qml.QQmlComponent__Ready { - return errors.New("QML not loaded properly") - } - - // Instead of creating component right away we use BeginCreate to stop right before binding evaluation. - // That is needed to set backend property so all bindings will be calculated properly. - rootObject := rootComponent.BeginCreate(f.engine.RootContext()) - // Check QML is loaded properly. - if rootObject == nil { - return errors.New("QML not created properly") - } - - rootObject.SetProperty("backend", f.qml.ToVariant()) - rootComponent.CompleteCreate() - - return nil -} - -func (f *FrontendQt) setShowSplashScreen() { - f.qml.SetShowSplashScreen(false) - - // Splash screen should not be shown to new users or after factory reset. - if f.bridge.IsFirstStart() { - return - } - - ver, err := semver.NewVersion(f.bridge.GetLastVersion()) - if err != nil { - f.log.WithError(err).WithField("last", f.bridge.GetLastVersion()).Debug("Cannot parse last version") - return - } - - // Current splash screen contains update on rebranding. Therefore, it - // should be shown only if the last used version was less than 2.2.0. - if ver.LessThan(semver.MustParse("2.2.0")) { - f.qml.SetShowSplashScreen(true) - } -} diff --git a/internal/frontend/qt/frontend_nogui.go b/internal/frontend/qt/frontend_nogui.go deleted file mode 100644 index 9e790aa6..00000000 --- a/internal/frontend/qt/frontend_nogui.go +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) 2022 Proton AG -// -// This file is part of Proton Mail Bridge. -// -// Proton Mail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Proton Mail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Proton Mail Bridge. If not, see . - -//go:build !build_qt -// +build !build_qt - -package qt - -import ( - "fmt" - "net/http" - - "github.com/ProtonMail/proton-bridge/v2/internal/config/settings" - "github.com/ProtonMail/proton-bridge/v2/internal/config/useragent" - "github.com/ProtonMail/proton-bridge/v2/internal/frontend/types" - "github.com/ProtonMail/proton-bridge/v2/internal/locations" - "github.com/ProtonMail/proton-bridge/v2/internal/updater" - "github.com/ProtonMail/proton-bridge/v2/pkg/listener" - "github.com/sirupsen/logrus" -) - -var log = logrus.WithField("pkg", "frontend-nogui") //nolint:gochecknoglobals - -type FrontendHeadless struct{} - -func New( - version, - buildVersion, - programName string, - showWindowOnStart bool, - panicHandler types.PanicHandler, - locations *locations.Locations, - settings *settings.Settings, - eventListener listener.Listener, - updater types.Updater, - userAgent *useragent.UserAgent, - bridge types.Bridger, - noEncConfirmator types.NoEncConfirmator, - restarter types.Restarter, -) *FrontendHeadless { - return &FrontendHeadless{} -} - -func (s *FrontendHeadless) Loop() error { - log.Info("Check status on localhost:8081") - http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, "Bridge is running") - }) - return http.ListenAndServe(":8081", nil) -} - -func (s *FrontendHeadless) NotifyManualUpdate(update updater.VersionInfo, canInstall bool) { - // NOTE: Save the update somewhere so that it can be installed when user chooses "install now". -} - -func (s *FrontendHeadless) WaitUntilFrontendIsReady() { -} - -func (s *FrontendHeadless) SetVersion(update updater.VersionInfo) { -} - -func (s *FrontendHeadless) NotifySilentUpdateInstalled() { -} - -func (s *FrontendHeadless) NotifySilentUpdateError(err error) { -} - -func (s *FrontendHeadless) InstanceExistAlert() {} diff --git a/internal/frontend/qt/frontend_settings.go b/internal/frontend/qt/frontend_settings.go deleted file mode 100644 index cbd1b7ed..00000000 --- a/internal/frontend/qt/frontend_settings.go +++ /dev/null @@ -1,218 +0,0 @@ -// Copyright (c) 2022 Proton AG -// -// This file is part of Proton Mail Bridge. -// -// Proton Mail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Proton Mail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Proton Mail Bridge. If not, see . - -//go:build build_qt -// +build build_qt - -package qt - -import ( - "runtime" - "time" - - "github.com/ProtonMail/proton-bridge/v2/internal/config/settings" - "github.com/ProtonMail/proton-bridge/v2/internal/frontend/clientconfig" - "github.com/ProtonMail/proton-bridge/v2/internal/frontend/theme" - "github.com/ProtonMail/proton-bridge/v2/pkg/keychain" - "github.com/ProtonMail/proton-bridge/v2/pkg/ports" - "github.com/therecipe/qt/core" -) - -func (f *FrontendQt) setIsDiskCacheEnabled() { - f.qml.SetIsDiskCacheEnabled(f.settings.GetBool(settings.CacheEnabledKey)) -} - -func (f *FrontendQt) setDiskCachePath() { - f.qml.SetDiskCachePath(core.QUrl_FromLocalFile(f.settings.Get(settings.CacheLocationKey))) -} - -func (f *FrontendQt) changeLocalCache(enableDiskCache bool, diskCachePath *core.QUrl) { - defer f.qml.ChangeLocalCacheFinished() - defer f.setIsDiskCacheEnabled() - defer f.setDiskCachePath() - - if enableDiskCache != f.settings.GetBool(settings.CacheEnabledKey) { - if enableDiskCache { - if err := f.bridge.EnableCache(); err != nil { - f.log.WithError(err).Error("Cannot enable disk cache") - } - } else { - if err := f.bridge.DisableCache(); err != nil { - f.log.WithError(err).Error("Cannot disable disk cache") - } - } - } - - _diskCachePath := diskCachePath.Path(core.QUrl__FullyDecoded) - if (runtime.GOOS == "windows") && (_diskCachePath[0] == '/') { - _diskCachePath = _diskCachePath[1:] - } - - if enableDiskCache && _diskCachePath != f.settings.Get(settings.CacheLocationKey) { - if err := f.bridge.MigrateCache(f.settings.Get(settings.CacheLocationKey), _diskCachePath); err != nil { - f.log.WithError(err).Error("The local cache location could not be changed.") - f.qml.CacheCantMove() - return - } - f.settings.Set(settings.CacheLocationKey, _diskCachePath) - } - - f.qml.CacheLocationChangeSuccess() - f.restart() -} - -func (f *FrontendQt) setIsAutostartOn() { - // GODT-1507 Windows: autostart needs to be created after Qt is initialized. - // GODT-1206: if preferences file says it should be on enable it here. - f.firstTimeAutostart.Do(func() { - shouldAutostartBeOn := f.settings.GetBool(settings.AutostartKey) - if f.bridge.IsFirstStart() || shouldAutostartBeOn { - if err := f.bridge.EnableAutostart(); err != nil { - f.log.WithField("prefs", shouldAutostartBeOn).WithError(err).Error("Failed to enable first autostart") - } - return - } - }) - f.qml.SetIsAutostartOn(f.bridge.IsAutostartEnabled()) -} - -func (f *FrontendQt) toggleAutostart(makeItEnabled bool) { - defer f.qml.ToggleAutostartFinished() - if makeItEnabled == f.bridge.IsAutostartEnabled() { - f.setIsAutostartOn() - return - } - - var err error - if makeItEnabled { - err = f.bridge.EnableAutostart() - } else { - err = f.bridge.DisableAutostart() - } - f.setIsAutostartOn() - - if err != nil { - f.log. - WithField("makeItEnabled", makeItEnabled). - WithField("isEnabled", f.qml.IsAutostartOn()). - WithError(err). - Error("Autostart change failed") - } -} - -func (f *FrontendQt) toggleDoH(makeItEnabled bool) { - f.bridge.SetProxyAllowed(makeItEnabled) - f.qml.SetIsDoHEnabled(f.bridge.GetProxyAllowed()) -} - -func (f *FrontendQt) toggleUseSSLforSMTP(makeItEnabled bool) { - if f.settings.GetBool(settings.SMTPSSLKey) == makeItEnabled { - f.qml.SetUseSSLforSMTP(makeItEnabled) - return - } - f.settings.SetBool(settings.SMTPSSLKey, makeItEnabled) - f.restart() -} - -func (f *FrontendQt) changePorts(imapPort, smtpPort int) { - defer f.qml.ChangePortFinished() - f.settings.SetInt(settings.IMAPPortKey, imapPort) - f.settings.SetInt(settings.SMTPPortKey, smtpPort) - f.restart() -} - -func (f *FrontendQt) isPortFree(port int) bool { - return ports.IsPortFree(port) -} - -func (f *FrontendQt) configureAppleMail(userID, address string) { - user, err := f.bridge.GetUser(userID) - if err != nil { - f.log.WithField("userID", userID).Error("Cannot configure AppleMail for user") - return - } - - needRestart, err := clientconfig.ConfigureAppleMail(user, address, f.settings) - if err != nil { - f.log.WithError(err).Error("Apple Mail config failed") - } - - if needRestart { - // There is delay needed for external window to open - time.Sleep(2 * time.Second) - f.restart() - } -} - -func (f *FrontendQt) triggerReset() { - defer f.qml.ResetFinished() - f.bridge.FactoryReset() - f.restart() -} - -func (f *FrontendQt) setKeychain() { - availableKeychain := []string{} - for chain := range keychain.Helpers { - availableKeychain = append(availableKeychain, chain) - } - f.qml.SetAvailableKeychain(availableKeychain) - f.qml.SetCurrentKeychain(f.bridge.GetKeychainApp()) -} - -func (f *FrontendQt) changeKeychain(wantKeychain string) { - defer f.qml.ChangeKeychainFinished() - - if f.bridge.GetKeychainApp() == wantKeychain { - return - } - - f.bridge.SetKeychainApp(wantKeychain) - f.restart() -} - -func (f *FrontendQt) restart() { - f.log.Info("Restarting bridge") - f.restarter.SetToRestart() - f.app.Exit(0) -} - -func (f *FrontendQt) quit() { - f.log.Warn("Your wish is my command.. I quit!") - f.app.Exit(0) -} - -func (f *FrontendQt) guiReady() { - f.initializationDone.Do(f.initializing.Done) -} - -func (f *FrontendQt) setColorScheme() { - current := f.settings.Get(settings.ColorScheme) - if !theme.IsAvailable(theme.Theme(current)) { - current = string(theme.DefaultTheme()) - f.settings.Set(settings.ColorScheme, current) - } - f.qml.SetColorSchemeName(current) -} - -func (f *FrontendQt) changeColorScheme(newScheme string) { - if !theme.IsAvailable(theme.Theme(newScheme)) { - f.log.WithField("scheme", newScheme).Warn("Color scheme not available") - return - } - f.settings.Set(settings.ColorScheme, newScheme) - f.setColorScheme() -} diff --git a/internal/frontend/qt/frontend_updates.go b/internal/frontend/qt/frontend_updates.go deleted file mode 100644 index 71fa2714..00000000 --- a/internal/frontend/qt/frontend_updates.go +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright (c) 2022 Proton AG -// -// This file is part of Proton Mail Bridge. -// -// Proton Mail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Proton Mail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Proton Mail Bridge. If not, see . - -//go:build build_qt -// +build build_qt - -package qt - -import ( - "sync" - - "github.com/ProtonMail/proton-bridge/v2/internal/config/settings" - "github.com/ProtonMail/proton-bridge/v2/internal/updater" - "github.com/pkg/errors" -) - -var checkingUpdates = sync.Mutex{} - -func (f *FrontendQt) checkUpdates() error { - version, err := f.updater.Check() - if err != nil { - return err - } - - f.SetVersion(version) - return nil -} - -func (f *FrontendQt) checkUpdatesAndNotify(isRequestFromUser bool) { - checkingUpdates.Lock() - defer checkingUpdates.Unlock() - defer f.qml.CheckUpdatesFinished() - - if err := f.checkUpdates(); err != nil { - f.log.WithError(err).Error("An error occurred while checking updates") - if isRequestFromUser { - f.qml.UpdateManualError() - } - return - } - - if !f.updater.IsUpdateApplicable(f.newVersionInfo) { - f.log.Debug("No need to update") - if isRequestFromUser { - f.qml.UpdateIsLatestVersion() - } - return - } - - if !f.updater.CanInstall(f.newVersionInfo) { - f.log.Debug("A manual update is required") - f.qml.UpdateManualError() - return - } - - if f.settings.GetBool(settings.AutoUpdateKey) { - // NOOP will update eventually - return - } - - if isRequestFromUser { - f.qml.UpdateManualReady(f.newVersionInfo.Version.String()) - } -} - -func (f *FrontendQt) updateForce() { - checkingUpdates.Lock() - defer checkingUpdates.Unlock() - - version := "" - if err := f.checkUpdates(); err == nil { - version = f.newVersionInfo.Version.String() - } - - f.qml.UpdateForce(version) -} - -func (f *FrontendQt) setIsAutomaticUpdateOn() { - f.qml.SetIsAutomaticUpdateOn(f.settings.GetBool(settings.AutoUpdateKey)) -} - -func (f *FrontendQt) toggleAutomaticUpdate(makeItEnabled bool) { - f.qml.SetIsAutomaticUpdateOn(makeItEnabled) - isEnabled := f.settings.GetBool(settings.AutoUpdateKey) - if makeItEnabled == isEnabled { - return - } - - f.settings.SetBool(settings.AutoUpdateKey, makeItEnabled) - - f.checkUpdatesAndNotify(false) -} - -func (f *FrontendQt) setIsBetaEnabled() { - channel := f.bridge.GetUpdateChannel() - f.qml.SetIsBetaEnabled(channel == updater.EarlyChannel) -} - -func (f *FrontendQt) toggleBeta(makeItEnabled bool) { - channel := updater.StableChannel - if makeItEnabled { - channel = updater.EarlyChannel - } - - f.bridge.SetUpdateChannel(channel) - - f.setIsBetaEnabled() - - // Immediately check the updates to set the correct landing page link. - f.checkUpdates() -} - -func (f *FrontendQt) installUpdate() { - checkingUpdates.Lock() - defer checkingUpdates.Unlock() - - if !f.updater.CanInstall(f.newVersionInfo) { - f.log.Warning("Skipping update installation, current version too old") - f.qml.UpdateManualError() - return - } - - if err := f.updater.InstallUpdate(f.newVersionInfo); err != nil { - if errors.Cause(err) == updater.ErrDownloadVerify { - f.log.WithError(err).Warning("Skipping update installation due to temporary error") - } else { - f.log.WithError(err).Error("The update couldn't be installed") - f.qml.UpdateManualError() - } - return - } - - f.qml.UpdateSilentRestartNeeded() -} diff --git a/internal/frontend/qt/frontend_users.go b/internal/frontend/qt/frontend_users.go deleted file mode 100644 index b5ee920d..00000000 --- a/internal/frontend/qt/frontend_users.go +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright (c) 2022 Proton AG -// -// This file is part of Proton Mail Bridge. -// -// Proton Mail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Proton Mail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Proton Mail Bridge. If not, see . - -//go:build build_qt -// +build build_qt - -package qt - -import ( - "context" - "encoding/base64" - "time" - - "github.com/ProtonMail/proton-bridge/v2/internal/events" - "github.com/ProtonMail/proton-bridge/v2/internal/users" - "github.com/ProtonMail/proton-bridge/v2/pkg/pmapi" -) - -func (f *FrontendQt) login(username, password string) { - var err error - f.password, err = base64.StdEncoding.DecodeString(password) - if err != nil { - f.log.WithError(err).Error("Cannot decode password") - f.qml.LoginUsernamePasswordError("Cannot decode password") - f.loginClean() - return - } - - f.authClient, f.auth, err = f.bridge.Login(username, f.password) - if err != nil { - if err == pmapi.ErrPasswordWrong { - // Remove error message since it is hardcodded in QML. - f.qml.LoginUsernamePasswordError("") - f.loginClean() - return - } - if err == pmapi.ErrPaidPlanRequired { - f.qml.LoginFreeUserError() - f.loginClean() - return - } - f.qml.LoginUsernamePasswordError(err.Error()) - f.loginClean() - return - } - - if f.auth.HasTwoFactor() { - f.qml.Login2FARequested(username) - return - } - if f.auth.HasMailboxPassword() { - f.qml.Login2PasswordRequested() - return - } - - f.finishLogin() -} - -func (f *FrontendQt) login2FA(username, code string) { - if f.auth == nil || f.authClient == nil { - f.log.Errorf("Login 2FA: authethication incomplete %p %p", f.auth, f.authClient) - f.qml.Login2FAErrorAbort("Missing authentication, try again.") - f.loginClean() - return - } - - twoFA, err := base64.StdEncoding.DecodeString(code) - if err != nil { - f.log.WithError(err).Error("Cannot decode 2fa code") - f.qml.LoginUsernamePasswordError("Cannot decode 2fa code") - f.loginClean() - return - } - - err = f.authClient.Auth2FA(context.Background(), string(twoFA)) - if err == pmapi.ErrBad2FACodeTryAgain { - f.log.Warn("Login 2FA: retry 2fa") - f.qml.Login2FAError("") - return - } - - if err == pmapi.ErrBad2FACode { - f.log.Warn("Login 2FA: abort 2fa") - f.qml.Login2FAErrorAbort("") - f.loginClean() - return - } - - if err != nil { - f.log.WithError(err).Warn("Login 2FA: failed.") - f.qml.Login2FAErrorAbort(err.Error()) - f.loginClean() - return - } - - if f.auth.HasMailboxPassword() { - f.qml.Login2PasswordRequested() - return - } - - f.finishLogin() -} - -func (f *FrontendQt) login2Password(username, mboxPassword string) { - var err error - f.password, err = base64.StdEncoding.DecodeString(mboxPassword) - if err != nil { - f.log.WithError(err).Error("Cannot decode mbox password") - f.qml.LoginUsernamePasswordError("Cannot decode mbox password") - f.loginClean() - return - } - - f.finishLogin() -} - -func (f *FrontendQt) finishLogin() { - defer f.loginClean() - - if len(f.password) == 0 || f.auth == nil || f.authClient == nil { - f.log. - WithField("hasPass", len(f.password) != 0). - WithField("hasAuth", f.auth != nil). - WithField("hasClient", f.authClient != nil). - Error("Finish login: authethication incomplete") - f.qml.Login2PasswordErrorAbort("Missing authentication, try again.") - return - } - - done := make(chan string) - f.eventListener.Add(events.UserChangeDone, done) - defer f.eventListener.Remove(events.UserChangeDone, done) - - user, err := f.bridge.FinishLogin(f.authClient, f.auth, f.password) - - if err != nil && err != users.ErrUserAlreadyConnected { - f.log.WithError(err).Errorf("Finish login failed") - f.qml.Login2PasswordErrorAbort(err.Error()) - return - } - - // The user changed should be triggerd by FinishLogin but it is not - // guaranteed when this is going to happen. Therefore we should wait - // until we receive the signal from userChanged function. - f.waitForUserChangeDone(done, user.ID()) - - index := f.qml.Users().indexByID(user.ID()) - f.log.WithField("index", index).Debug("Login finished") - defer f.qml.LoginFinished(index) - - if err == users.ErrUserAlreadyConnected { - f.log.WithError(err).Error("User already logged in") - f.qml.LoginAlreadyLoggedIn(index) - } -} - -func (f *FrontendQt) waitForUserChangeDone(done <-chan string, userID string) { - for { - select { - case changedID := <-done: - if changedID == userID { - return - } - case <-time.After(2 * time.Second): - f.log.WithField("ID", userID).Warning("Login finished but user not added within 2 seconds") - return - } - } -} - -func (f *FrontendQt) loginAbort(username string) { - f.loginClean() -} - -func (f *FrontendQt) loginClean() { - f.auth = nil - f.authClient = nil - for i := range f.password { - f.password[i] = '\x00' - } - f.password = f.password[0:0] -} diff --git a/internal/frontend/qt/log/log.cpp b/internal/frontend/qt/log/log.cpp deleted file mode 100644 index 64ca9589..00000000 --- a/internal/frontend/qt/log/log.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) 2022 Proton AG -// -// This file is part of Proton Mail Bridge. -// -// Proton Mail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Proton Mail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Proton Mail Bridge. If not, see . - - -// +build build_qt - -#include "log.h" -#include "_cgo_export.h" - -#include -#include -#include -#include -#include - -void messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) -{ - Q_UNUSED( type ) - Q_UNUSED( context ) - QByteArray localMsg = msg.toUtf8().prepend("WHITESPACE"); - logMsgPacked( - const_cast( (localMsg.constData()) +10 ), - localMsg.size()-10 - ); -} - -void InstallMessageHandler() { - qInstallMessageHandler(messageHandler); -} - diff --git a/internal/frontend/qt/log/log.go b/internal/frontend/qt/log/log.go deleted file mode 100644 index 0c180430..00000000 --- a/internal/frontend/qt/log/log.go +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) 2022 Proton AG -// -// This file is part of Proton Mail Bridge. -// -// Proton Mail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Proton Mail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Proton Mail Bridge. If not, see . - -//go:build build_qt -// +build build_qt - -// Package log redirects QML logs to logrus -package log - -//#include "log.h" -import "C" - -import ( - "github.com/sirupsen/logrus" - "github.com/therecipe/qt/core" -) - -var logQML = logrus.WithField("pkg", "frontent/qml") - -// InstallMessageHandler is registering logQML as logger for QML calls. -func InstallMessageHandler() { - C.InstallMessageHandler() -} - -//export logMsgPacked -func logMsgPacked(data *C.char, len C.int) { - logQML.Warn(C.GoStringN(data, len)) -} - -// logDummy is here to trigger qtmoc to create cgo instructions -type logDummy struct { - core.QObject -} diff --git a/internal/frontend/qt/qml_backend.go b/internal/frontend/qt/qml_backend.go deleted file mode 100644 index 04d38be7..00000000 --- a/internal/frontend/qt/qml_backend.go +++ /dev/null @@ -1,317 +0,0 @@ -// Copyright (c) 2022 Proton AG -// -// This file is part of Proton Mail Bridge. -// -// Proton Mail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Proton Mail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Proton Mail Bridge. If not, see . - -//go:build build_qt -// +build build_qt - -package qt - -import ( - "runtime" - - "github.com/ProtonMail/proton-bridge/v2/internal/bridge" - "github.com/ProtonMail/proton-bridge/v2/internal/config/settings" - dockIcon "github.com/ProtonMail/proton-bridge/v2/internal/frontend/qt/dockicon" - "github.com/therecipe/qt/core" -) - -func init() { - QMLBackend_QRegisterMetaType() -} - -// QMLBackend connects QML frontend with Go backend. -type QMLBackend struct { - core.QObject - - _ func() *core.QPoint `slot:"getCursorPos"` - _ func() `slot:"guiReady"` - _ func() `slot:"quit"` - _ func() `slot:"restart"` - - _ bool `property:showOnStartup` - _ bool `property:showSplashScreen` - - _ bool `property:dockIconVisible` - - _ QMLUserModel `property:"users"` - - // TODO copy stuff from Bridge_test.qml backend object - _ string `property:"goos"` - - _ func(username, password string) `slot:"login"` - _ func(username, code string) `slot:"login2FA"` - _ func(username, password string) `slot:"login2Password"` - _ func(username string) `slot:"loginAbort"` - _ func(errorMsg string) `signal:"loginUsernamePasswordError"` - _ func() `signal:"loginFreeUserError"` - _ func(errorMsg string) `signal:"loginConnectionError"` - _ func(username string) `signal:"login2FARequested"` - _ func(errorMsg string) `signal:"login2FAError"` - _ func(errorMsg string) `signal:"login2FAErrorAbort"` - _ func() `signal:"login2PasswordRequested"` - _ func(errorMsg string) `signal:"login2PasswordError"` - _ func(errorMsg string) `signal:"login2PasswordErrorAbort"` - _ func(index int) `signal:"loginFinished"` - _ func(index int) `signal:"loginAlreadyLoggedIn"` - - _ func() `signal:"internetOff"` - _ func() `signal:"internetOn"` - - _ func(version string) `signal:"updateManualReady"` - _ func() `signal:"updateManualRestartNeeded"` - _ func() `signal:"updateManualError"` - _ func(version string) `signal:"updateForce"` - _ func() `signal:"updateForceError"` - _ func() `signal:"updateSilentRestartNeeded"` - _ func() `signal:"updateSilentError"` - _ func() `signal:"updateIsLatestVersion"` - _ func() `slot:"checkUpdates"` - _ func() `signal:"checkUpdatesFinished"` - _ func() `slot:"installUpdate"` - - _ bool `property:"isDiskCacheEnabled"` - _ core.QUrl `property:"diskCachePath"` - _ func() `signal:"cacheUnavailable"` - _ func() `signal:"cacheCantMove"` - _ func() `signal:"cacheLocationChangeSuccess"` - _ func() `signal:"diskFull"` - _ func(enableDiskCache bool, diskCachePath core.QUrl) `slot:"changeLocalCache"` - _ func() `signal:"changeLocalCacheFinished"` - - _ bool `property:"isFirstGUIStart"` - - _ bool `property:"isAutomaticUpdateOn"` - _ func(makeItActive bool) `slot:"toggleAutomaticUpdate"` - - _ bool `property:"isAutostartOn"` - _ func(makeItActive bool) `slot:"toggleAutostart"` - _ func() `signal:"toggleAutostartFinished"` - - _ bool `property:"isBetaEnabled"` - _ func(makeItActive bool) `slot:"toggleBeta"` - - _ bool `property:"isDoHEnabled"` - _ func(makeItActive bool) `slot:"toggleDoH"` - - _ bool `property:"useSSLforSMTP"` - _ func(makeItActive bool) `slot:"toggleUseSSLforSMTP"` - _ func() `signal:"toggleUseSSLFinished"` - - _ string `property:"hostname"` - _ int `property:"portIMAP"` - _ int `property:"portSMTP"` - _ func(imapPort, smtpPort int) `slot:"changePorts"` - _ func(port int) bool `slot:"isPortFree"` - _ func() `signal:"changePortFinished"` - _ func() `signal:"portIssueIMAP"` - _ func() `signal:"portIssueSMTP"` - - _ func() `slot:"triggerReset"` - _ func() `signal:"resetFinished"` - - _ string `property:"version"` - _ core.QUrl `property:"logsPath"` - _ core.QUrl `property:"licensePath"` - _ core.QUrl `property:"releaseNotesLink"` - _ core.QUrl `property:"dependencyLicensesLink"` - _ core.QUrl `property:"landingPageLink"` - - _ string `property:"colorSchemeName"` - _ func(string) `slot:"changeColorScheme"` - _ string `property:"currentEmailClient"` - _ func() `slot:"updateCurrentMailClient"` - _ func(description, address, emailClient string, includeLogs bool) `slot:"reportBug"` - _ func() `signal:"reportBugFinished"` - _ func() `signal:"bugReportSendSuccess"` - _ func() `signal:"bugReportSendError"` - - _ []string `property:"availableKeychain"` - _ string `property:"currentKeychain"` - _ func(keychain string) `slot:"changeKeychain"` - _ func() `signal:"changeKeychainFinished"` - _ func() `signal:"notifyHasNoKeychain"` - _ func() `signal:"notifyRebuildKeychain"` - - _ func(email string) `signal:noActiveKeyForRecipient` - _ func() `signal:showMainWindow` - - _ func(address string) `signal:addressChanged` - _ func(address string) `signal:addressChangedLogout` - _ func(username string) `signal:userDisconnected` - _ func() `signal:apiCertIssue` - - _ func(userID string) `signal:userChanged` - - _ bool `property:"isAllMailVisible"` - _ func(isDisabled bool) `slot:"changeIsAllMailVisible"` -} - -func (q *QMLBackend) setup(f *FrontendQt) { - q.ConnectGetCursorPos(getCursorPos) - q.ConnectQuit(f.quit) - q.ConnectRestart(f.restart) - q.ConnectGuiReady(f.guiReady) - - q.ConnectIsShowOnStartup(func() bool { - return f.showOnStartup - }) - - q.ConnectIsDockIconVisible(dockIcon.GetDockIconVisibleState) - q.ConnectSetDockIconVisible(dockIcon.SetDockIconVisibleState) - - um := NewQMLUserModel(q) - um.f = f - q.SetUsers(um) - um.load() - - q.ConnectUserChanged(um.userChanged) - - q.SetGoos(runtime.GOOS) - - q.ConnectLogin(func(u, p string) { - go func() { - defer f.panicHandler.HandlePanic() - f.login(u, p) - }() - }) - q.ConnectLogin2FA(func(u, p string) { - go func() { - defer f.panicHandler.HandlePanic() - f.login2FA(u, p) - }() - }) - q.ConnectLogin2Password(func(u, p string) { - go func() { - defer f.panicHandler.HandlePanic() - f.login2Password(u, p) - }() - }) - q.ConnectLoginAbort(func(u string) { - go func() { - defer f.panicHandler.HandlePanic() - f.loginAbort(u) - }() - }) - - go func() { - defer f.panicHandler.HandlePanic() - f.checkUpdatesAndNotify(false) - }() - q.ConnectCheckUpdates(func() { - go func() { - defer f.panicHandler.HandlePanic() - f.checkUpdatesAndNotify(true) - }() - }) - - q.ConnectInstallUpdate(func() { - go func() { - defer f.panicHandler.HandlePanic() - f.installUpdate() - }() - }) - - f.setIsDiskCacheEnabled() - f.setDiskCachePath() - q.ConnectChangeLocalCache(func(e bool, d *core.QUrl) { - go func() { - defer f.panicHandler.HandlePanic() - f.changeLocalCache(e, d) - }() - }) - - f.setIsAutomaticUpdateOn() - q.ConnectToggleAutomaticUpdate(func(m bool) { - go func() { - defer f.panicHandler.HandlePanic() - f.toggleAutomaticUpdate(m) - }() - }) - - f.setIsAutostartOn() - q.ConnectToggleAutostart(f.toggleAutostart) - - f.setIsBetaEnabled() - q.ConnectToggleBeta(func(m bool) { - go func() { - defer f.panicHandler.HandlePanic() - f.toggleBeta(m) - }() - }) - - q.SetIsDoHEnabled(f.bridge.GetProxyAllowed()) - q.ConnectToggleDoH(f.toggleDoH) - - q.SetUseSSLforSMTP(f.settings.GetBool(settings.SMTPSSLKey)) - q.ConnectToggleUseSSLforSMTP(f.toggleUseSSLforSMTP) - - q.SetHostname(bridge.Host) - q.SetPortIMAP(f.settings.GetInt(settings.IMAPPortKey)) - q.SetPortSMTP(f.settings.GetInt(settings.SMTPPortKey)) - q.ConnectChangePorts(f.changePorts) - q.ConnectIsPortFree(f.isPortFree) - - q.ConnectTriggerReset(func() { - go func() { - defer f.panicHandler.HandlePanic() - f.triggerReset() - }() - }) - - f.setShowSplashScreen() - f.setVersion() - f.setLogsPath() - // release notes link is set by update - f.setLicensePath() - - f.setColorScheme() - q.ConnectChangeColorScheme(func(newScheme string) { - go func() { - defer f.panicHandler.HandlePanic() - f.changeColorScheme(newScheme) - }() - }) - - f.setCurrentEmailClient() - q.ConnectUpdateCurrentMailClient(func() { - go func() { - defer f.panicHandler.HandlePanic() - f.setCurrentEmailClient() - }() - }) - q.ConnectReportBug(func(d, a, e string, i bool) { - go func() { - defer f.panicHandler.HandlePanic() - f.reportBug(d, a, e, i) - }() - }) - - f.setKeychain() - q.ConnectChangeKeychain(func(k string) { - go func() { - defer f.panicHandler.HandlePanic() - f.changeKeychain(k) - }() - }) - - q.SetIsAllMailVisible(f.bridge.IsAllMailVisible()) - q.ConnectChangeIsAllMailVisible(func(isVisible bool) { - f.bridge.SetIsAllMailVisible(isVisible) - f.qml.SetIsAllMailVisible(isVisible) - }) - -} diff --git a/internal/frontend/qt/qml_users.go b/internal/frontend/qt/qml_users.go deleted file mode 100644 index 4f2a8813..00000000 --- a/internal/frontend/qt/qml_users.go +++ /dev/null @@ -1,297 +0,0 @@ -// Copyright (c) 2022 Proton AG -// -// This file is part of Proton Mail Bridge. -// -// Proton Mail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Proton Mail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Proton Mail Bridge. If not, see . - -//go:build build_qt -// +build build_qt - -package qt - -import ( - "sync" - - "github.com/ProtonMail/proton-bridge/v2/internal/events" - "github.com/ProtonMail/proton-bridge/v2/internal/frontend/types" - "github.com/therecipe/qt/core" -) - -func init() { - QMLUser_QRegisterMetaType() - QMLUserModel_QRegisterMetaType() -} - -// QMLUserModel stores list of of users -type QMLUserModel struct { - core.QAbstractListModel - - _ map[int]*core.QByteArray `property:"roles"` - _ int `property:"count"` - _ func() `constructor:"init"` - _ func(row int) *core.QVariant `slot:"get"` - - userIDs []string - userByID map[string]*QMLUser - access sync.RWMutex - f *FrontendQt -} - -func (um *QMLUserModel) init() { - um.access.Lock() - defer um.access.Unlock() - um.SetCount(0) - um.ConnectRowCount(um.rowCount) - um.ConnectRoleNames(um.roleNames) - um.ConnectData(um.data) - um.ConnectGet(um.get) - um.ConnectCount(func() int { - um.access.RLock() - defer um.access.RUnlock() - return len(um.userIDs) - }) - um.userIDs = []string{} - um.userByID = map[string]*QMLUser{} -} - -func (um *QMLUserModel) roleNames() map[int]*core.QByteArray { - return map[int]*core.QByteArray{ - int(core.Qt__DisplayRole): core.NewQByteArray2("user", -1), - } -} - -func (um *QMLUserModel) data(index *core.QModelIndex, property int) *core.QVariant { - if !index.IsValid() { - um.f.log.WithField("size", len(um.userIDs)).Info("Trying to get user by invalid index") - return core.NewQVariant() - } - return um.get(index.Row()) -} - -func (um *QMLUserModel) get(index int) *core.QVariant { - um.access.Lock() - defer um.access.Unlock() - if index < 0 || index >= len(um.userIDs) { - um.f.log.WithField("index", index).WithField("size", len(um.userIDs)).Info("Trying to get user by wrong index") - return core.NewQVariant() - } - - u, err := um.getUserByID(um.userIDs[index]) - if err != nil { - um.f.log.WithError(err).Error("Cannot get user from backend") - return core.NewQVariant() - } - return u.ToVariant() -} - -func (um *QMLUserModel) getUserByID(userID string) (*QMLUser, error) { - u, ok := um.userByID[userID] - if ok { - return u, nil - } - - user, err := um.f.bridge.GetUser(userID) - if err != nil { - return nil, err - } - - u = newQMLUserFromBacked(um, user) - um.userByID[userID] = u - return u, nil -} - -func (um *QMLUserModel) rowCount(*core.QModelIndex) int { - um.access.RLock() - defer um.access.RUnlock() - return len(um.userIDs) -} - -func (um *QMLUserModel) setCount() { - um.SetCount(len(um.userIDs)) -} - -func (um *QMLUserModel) addUser(userID string) { - um.BeginInsertRows(core.NewQModelIndex(), len(um.userIDs), len(um.userIDs)) - um.access.Lock() - if um.indexByIDNotSafe(userID) < 0 { - um.userIDs = append(um.userIDs, userID) - } - um.access.Unlock() - um.EndInsertRows() - um.setCount() -} - -func (um *QMLUserModel) removeUser(row int) { - um.BeginRemoveRows(core.NewQModelIndex(), row, row) - um.access.Lock() - id := um.userIDs[row] - um.userIDs = append(um.userIDs[:row], um.userIDs[row+1:]...) - delete(um.userByID, id) - um.access.Unlock() - um.EndRemoveRows() - um.setCount() -} - -func (um *QMLUserModel) clear() { - um.BeginResetModel() - um.access.Lock() - um.userIDs = []string{} - um.userByID = map[string]*QMLUser{} - um.SetCount(0) - um.access.Unlock() - um.EndResetModel() -} - -func (um *QMLUserModel) load() { - um.clear() - - for _, user := range um.f.bridge.GetUsers() { - um.addUser(user.ID()) - - // We need mark that all existing users already saw setup - // guide. This it is OK to construct QML here because it is in main thread. - u, err := um.getUserByID(user.ID()) - if err != nil { - um.f.log.WithError(err).Error("Cannot get QMLUser while loading users") - } - u.SetSetupGuideSeen(true) - } - - // If there are no active accounts. - if um.Count() == 0 { - um.f.log.Info("No active accounts") - } -} - -func (um *QMLUserModel) userChanged(userID string) { - defer um.f.eventListener.Emit(events.UserChangeDone, userID) - - index := um.indexByIDNotSafe(userID) - user, err := um.f.bridge.GetUser(userID) - - if user == nil || err != nil { - if index >= 0 { // delete existing user - um.removeUser(index) - } - // if not exiting do nothing - return - } - - if index < 0 { // add non-existing user - um.addUser(userID) - return - } - - // update exiting user - um.userByID[userID].update(user) -} - -func (um *QMLUserModel) indexByIDNotSafe(wantID string) int { - for i, id := range um.userIDs { - if id == wantID { - return i - } - } - return -1 -} - -func (um *QMLUserModel) indexByID(id string) int { - um.access.RLock() - defer um.access.RUnlock() - - return um.indexByIDNotSafe(id) -} - -// QMLUser holds data, slots and signals and for user. -type QMLUser struct { - core.QObject - - _ string `property:"username"` - _ string `property:"avatarText"` - _ bool `property:"loggedIn"` - _ bool `property:"splitMode"` - _ bool `property:"setupGuideSeen"` - _ float32 `property:"usedBytes"` - _ float32 `property:"totalBytes"` - _ string `property:"password"` - _ []string `property:"addresses"` - - _ func(makeItActive bool) `slot:"toggleSplitMode"` - _ func() `signal:"toggleSplitModeFinished"` - _ func() `slot:"logout"` - _ func() `slot:"remove"` - _ func(address string) `slot:"configureAppleMail"` - - ID string -} - -func newQMLUserFromBacked(um *QMLUserModel, user types.User) *QMLUser { - qu := NewQMLUser(um) - qu.ID = user.ID() - - qu.update(user) - - qu.ConnectToggleSplitMode(func(activateSplitMode bool) { - go func() { - defer um.f.panicHandler.HandlePanic() - defer qu.ToggleSplitModeFinished() - if activateSplitMode == user.IsCombinedAddressMode() { - user.SwitchAddressMode() - } - qu.SetSplitMode(!user.IsCombinedAddressMode()) - }() - }) - - qu.ConnectLogout(func() { - qu.SetLoggedIn(false) - go func() { - defer um.f.panicHandler.HandlePanic() - user.Logout() - }() - }) - - qu.ConnectRemove(func() { - go func() { - defer um.f.panicHandler.HandlePanic() - - // TODO: remove preferences - if err := um.f.bridge.DeleteUser(qu.ID, false); err != nil { - um.f.log.WithError(err).Error("Failed to remove user") - // TODO: notification - } - }() - }) - - qu.ConnectConfigureAppleMail(func(address string) { - go func() { - defer um.f.panicHandler.HandlePanic() - um.f.configureAppleMail(qu.ID, address) - }() - }) - - return qu -} - -func (qu *QMLUser) update(user types.User) { - username := user.Username() - qu.SetAvatarText(getInitials(username)) - qu.SetUsername(username) - qu.SetLoggedIn(user.IsConnected()) - qu.SetSplitMode(!user.IsCombinedAddressMode()) - qu.SetSetupGuideSeen(false) - qu.SetUsedBytes(float32(user.UsedBytes())) - qu.SetTotalBytes(float32(user.TotalBytes())) - qu.SetPassword(user.GetBridgePassword()) - qu.SetAddresses(user.GetAddresses()) -} diff --git a/internal/frontend/qt6/AppController.cpp b/internal/frontend/qt6/AppController.cpp new file mode 100644 index 00000000..c234aade --- /dev/null +++ b/internal/frontend/qt6/AppController.cpp @@ -0,0 +1,45 @@ +// Copyright (c) 2022 Proton AG +// +// This file is part of Proton Mail Bridge. +// +// Proton Mail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Proton Mail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Proton Mail Bridge. If not, see . + + +#include "Pch.h" +#include "AppController.h" +#include "QMLBackend.h" +#include "GRPC/GRPCClient.h" +#include "Log.h" + + +//**************************************************************************************************************************************************** +/// \return The AppController instance. +//**************************************************************************************************************************************************** +AppController &app() +{ + static AppController app; + return app; +} + + +//**************************************************************************************************************************************************** +// +//**************************************************************************************************************************************************** +AppController::AppController() + : backend_(std::make_unique()) + , grpc_(std::make_unique()) + , log_(std::make_unique()) +{ + +} diff --git a/internal/frontend/qt6/AppController.h b/internal/frontend/qt6/AppController.h new file mode 100644 index 00000000..cf398c62 --- /dev/null +++ b/internal/frontend/qt6/AppController.h @@ -0,0 +1,59 @@ +// Copyright (c) 2022 Proton AG +// +// This file is part of Proton Mail Bridge. +// +// Proton Mail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Proton Mail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Proton Mail Bridge. If not, see . + + +#ifndef BRIDGE_QT6_APP_CONTROLLER_H +#define BRIDGE_QT6_APP_CONTROLLER_H + + +class QMLBackend; +class GRPCClient; +class Log; + + +//**************************************************************************************************************************************************** +/// \brief App controller class. +//**************************************************************************************************************************************************** +class AppController: public QObject +{ + Q_OBJECT + friend AppController& app(); + +public: // member functions. + AppController(AppController const&) = delete; ///< Disabled copy-constructor. + AppController(AppController&&) = delete; ///< Disabled assignment copy-constructor. + ~AppController() override = default; ///< Destructor. + AppController& operator=(AppController const&) = delete; ///< Disabled assignment operator. + AppController& operator=(AppController&&) = delete; ///< Disabled move assignment operator. + QMLBackend& backend() { return *backend_; } ///< Return a reference to the backend. + GRPCClient& grpc() { return *grpc_; } ///< Return a reference to the GRPC client. + Log& log() { return *log_; } ///< Return a reference to the log. + +private: // member functions + AppController(); ///< Default constructor. + +private: // data members + std::unique_ptr backend_; ///< The backend. + std::unique_ptr grpc_; ///< The RPC client. + std::unique_ptr log_; ///< The log. +}; + + +AppController& app(); ///< Return a reference to the app controller. + + +#endif // BRIDGE_QT6_APP_CONTROLLER_H diff --git a/internal/frontend/qt6/CMakeLists.txt b/internal/frontend/qt6/CMakeLists.txt new file mode 100644 index 00000000..286664ef --- /dev/null +++ b/internal/frontend/qt6/CMakeLists.txt @@ -0,0 +1,136 @@ +# Copyright (c) 2022 Proton AG +# +# This file is part of Proton Mail Bridge. +# +# Proton Mail Bridge is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Proton Mail Bridge is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Proton Mail Bridge. If not, see . + +cmake_minimum_required(VERSION 3.22) + +set(CMAKE_OSX_ARCHITECTURES x86_64) # needs to be set before the first project() directive. + +#We rely on vcpkg for to get gRPC+Protobuf +if (NOT DEFINED ENV{VCPKG_ROOT}) + message(FATAL_ERROR "vcpkg is required. Install vcpkg and define VCPKG_ROOT to point the the vcpkg installation folder. (e.g. ~/vcpkg/") +endif() +if (APPLE) + set(VCPKG_TARGET_TRIPLET x64-osx) +endif() +if (WIN32) + set(VCPKG_TARGET_TRIPLET x64-mingw-static) +endif() +set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" CACHE STRING "toolchain") + + +project(bridge_qt6 LANGUAGES CXX) +if (APPLE) # On macOS, we have some Objective-C++ code in DockIcon to deal with ... the dock icon. + enable_language(OBJC OBJCXX) +endif() + +if (NOT DEFINED ENV{QT5DIR}) + message(FATAL_ERROR "QT5DIR needs to be defined and point to the root of your Qt5 folder (e.g. /Users/MyName/Qt/5.10.1/clang_64).") +endif() + + +set(CMAKE_PREFIX_PATH $ENV{QT5DIR} ${CMAKE_PREFIX_PATH}) +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) +find_package(Protobuf CONFIG REQUIRED) +message(STATUS "Using protobuf ${Protobuf_VERSION}") + + +find_package(grpc CONFIG REQUIRED) +message(STATUS "Using gRPC ${gRPC_VERSION}") + + +if (APPLE) # We need to link the Cocoa framework for the dock icon. + find_library(COCOA_LIBRARY Cocoa REQUIRED) +endif() + + +find_package(Qt5 COMPONENTS + Core + Quick + Qml + QuickControls2 + REQUIRED) + +find_program(PROTOC_EXE protoc) +find_program(GRPC_CPP_PLUGIN grpc_cpp_plugin) +set(PROTO_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../grpc") +set(PROTO_FILE "${PROTO_DIR}/bridge.proto") +set(GRPC_OUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/GRPC") +set(PROTO_CPP_FILE "${GRPC_OUT_DIR}/bridge.pb.cc") +set(PROTO_H_FILE "${GRPC_OUT_DIR}/bridge.pb.h") +set(GRPC_CPP_FILE "${GRPC_OUT_DIR}/bridge.grpc.pb.cc") +set(GRPC_H_FILE "${GRPC_OUT_DIR}/bridge.grpc.pb.h") +if (APPLE) + set(DOCK_ICON_SRC_FILE DockIcon/DockIcon.mm) +else() + set(DOCK_ICON_SRC_FILE DockIcon/DockIcon.cpp) +endif() + +add_custom_command( + OUTPUT + ${PROTO_CPP_FILE} + ${PROTO_H_FILE} + ${GRPC_CPP_FILE} + ${GRPC_H_FILE} + COMMAND + ${PROTOC_EXE} + ARGS + --proto_path=${PROTO_DIR} + --plugin=protoc-gen-grpc="${GRPC_CPP_PLUGIN}" + --cpp_out=${GRPC_OUT_DIR} + --grpc_out=${GRPC_OUT_DIR} + ${PROTO_FILE} + DEPENDS + ${PROTO_FILE} + COMMENT "Generating gPRC/Protobuf C++ code" +) + +add_executable(bridge_qt6 + ${PROTO_CPP_FILE} ${PROTO_H_FILE} ${GRPC_CPP_FILE} ${GRPC_H_FILE} + AppController.cpp AppController.h + EventStreamWorker.cpp EventStreamWorker.h + Exception.cpp Exception.h + Log.cpp Log.h + main.cpp + Pch.h + QMLBackend.cpp QMLBackend.h + ${DOCK_ICON_SRC_FILE} DockIcon/DockIcon.h + GRPC/GRPCClient.cpp GRPC/GRPCClient.h + GRPC/GRPCUtils.cpp GRPC/GRPCUtils.h + User/User.cpp User/User.h User/UserList.cpp User/UserList.h + Worker/Overseer.cpp Worker/Overseer.h + Worker/Worker.h) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +target_precompile_headers(bridge_qt6 PRIVATE Pch.h) + +target_link_libraries(bridge_qt6 + Qt5::Core + Qt5::Quick + Qt5::Qml + Qt5::QuickControls2 + protobuf::libprotobuf + gRPC::grpc++ + ) + +if (APPLE) +target_link_libraries(bridge_qt6 ${COCOA_LIBRARY}) +endif() diff --git a/internal/frontend/qt/dockicon/dockicon_default.go b/internal/frontend/qt6/DockIcon/DockIcon.cpp similarity index 81% rename from internal/frontend/qt/dockicon/dockicon_default.go rename to internal/frontend/qt6/DockIcon/DockIcon.cpp index 9ec3625e..d9901910 100644 --- a/internal/frontend/qt/dockicon/dockicon_default.go +++ b/internal/frontend/qt6/DockIcon/DockIcon.cpp @@ -15,13 +15,15 @@ // You should have received a copy of the GNU General Public License // along with Proton Mail Bridge. If not, see . -//go:build !darwin && build_qt -// +build !darwin,build_qt -package dockicon +#include "Pch.h" -func SetDockIconVisibleState(visible bool) {} -func GetDockIconVisibleState() bool { - return true -} +#ifndef Q_OS_MACOS + + +void setDockIconVisibleState(bool visible) { Q_UNUSED(visible) } +bool getDockIconVisibleState() { return true; } + + +#endif \ No newline at end of file diff --git a/internal/frontend/qt/log/log.h b/internal/frontend/qt6/DockIcon/DockIcon.h similarity index 74% rename from internal/frontend/qt/log/log.h rename to internal/frontend/qt6/DockIcon/DockIcon.h index a20c8396..f312d064 100644 --- a/internal/frontend/qt/log/log.h +++ b/internal/frontend/qt6/DockIcon/DockIcon.h @@ -15,22 +15,13 @@ // You should have received a copy of the GNU General Public License // along with Proton Mail Bridge. If not, see . -#pragma once -#ifndef LOGRUS_QML_LOG_H -#define LOGRUS_QML_LOG_H +#ifndef BRIDGE_QT6_DOCK_ICON_H +#define BRIDGE_QT6_DOCK_ICON_H -#include -#ifdef __cplusplus -extern "C" { -#endif // C++ +void setDockIconVisibleState(bool visible); ///< Set the DOCK icon visibility state +bool getDockIconVisibleState(); ///< Get the Dock icon visibility state - void InstallMessageHandler(); - ; -#ifdef __cplusplus -} -#endif // C++ - -#endif // LOGRUS_QML_LOG_H +#endif // #ifndef BRIDGE_QT6_DOCK_ICON_H diff --git a/internal/frontend/qt/dockicon/DockIcon.m b/internal/frontend/qt6/DockIcon/DockIcon.mm similarity index 86% rename from internal/frontend/qt/dockicon/DockIcon.m rename to internal/frontend/qt6/DockIcon/DockIcon.mm index 8059064b..0b2bfd4f 100644 --- a/internal/frontend/qt/dockicon/DockIcon.m +++ b/internal/frontend/qt6/DockIcon/DockIcon.mm @@ -15,13 +15,16 @@ // You should have received a copy of the GNU General Public License // along with Proton Mail Bridge. If not, see . -// +build darwin -// +build build_qt -#include "DockIcon.h" +#include "Pch.h" #include +#include "DockIcon.h" -void SetDockIconVisibleState(bool visible) { + +#ifdef Q_OS_MACOS + + +void setDockIconVisibleState(bool visible) { if (visible) { [NSApp setActivationPolicy: NSApplicationActivationPolicyRegular]; return; @@ -31,12 +34,16 @@ void SetDockIconVisibleState(bool visible) { } } -bool GetDockIconVisibleState() { + +bool getDockIconVisibleState() { switch ([NSApp activationPolicy]) { case NSApplicationActivationPolicyAccessory: case NSApplicationActivationPolicyProhibited: - return false; + return false; case NSApplicationActivationPolicyRegular: - return true; + return true; } } + + +#endif // #ifdef Q_OS_MACOS \ No newline at end of file diff --git a/internal/frontend/qt6/Doxyfile b/internal/frontend/qt6/Doxyfile new file mode 100644 index 00000000..072a8b4d --- /dev/null +++ b/internal/frontend/qt6/Doxyfile @@ -0,0 +1,2656 @@ +# Copyright (c) 2022 Proton AG +# +# This file is part of Proton Mail Bridge. +# +# Proton Mail Bridge is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Proton Mail Bridge is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Proton Mail Bridge. If not, see . +# Doxyfile 1.9.4 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). +# +# Note: +# +# Use doxygen to compare the used configuration file with the template +# configuration file: +# doxygen -x [configFile] +# Use doxygen to compare the used configuration file with the template +# configuration file without replacing the environment variables: +# doxygen -x_noenv [configFile] + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the configuration +# file that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = "Proton Mail Bridge Qt6" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = _doc + +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 4096 +# sub-directories (in 2 levels) under the output directory of each output format +# and will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. Adapt CREATE_SUBDIRS_LEVEL to +# control the number of sub-directories. +# The default value is: NO. + +CREATE_SUBDIRS = YES + +# Controls the number of sub-directories that will be created when +# CREATE_SUBDIRS tag is set to YES. Level 0 represents 16 directories, and every +# level increment doubles the number of directories, resulting in 4096 +# directories at level 8 which is the default and also the maximum value. The +# sub-directories are organized in 2 levels, the first level always has a fixed +# numer of 16 directories. +# Minimum value: 0, maximum value: 8, default value: 8. +# This tag requires that the tag CREATE_SUBDIRS is set to YES. + +CREATE_SUBDIRS_LEVEL = 8 + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Bulgarian, +# Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, English +# (United States), Esperanto, Farsi (Persian), Finnish, French, German, Greek, +# Hindi, Hungarian, Indonesian, Italian, Japanese, Japanese-en (Japanese with +# English messages), Korean, Korean-en (Korean with English messages), Latvian, +# Lithuanian, Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, +# Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, +# Swedish, Turkish, Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = NO + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = NO + +# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line +# such as +# /*************** +# as being the beginning of a Javadoc-style comment "banner". If set to NO, the +# Javadoc-style will behave just like regular comments and it will not be +# interpreted by doxygen. +# The default value is: NO. + +JAVADOC_BANNER = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# By default Python docstrings are displayed as preformatted text and doxygen's +# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the +# doxygen's special commands can be used and the contents of the docstring +# documentation blocks is shown as doxygen documentation. +# The default value is: YES. + +PYTHON_DOCSTRING = YES + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 3 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:^^" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". Note that you cannot put \n's in the value part of an alias +# to insert newlines (in the resulting output). You can put ^^ in the value part +# of an alias to insert a newline as if a physical newline was in the original +# file. When you need a literal { or } or , in the value part of an alias you +# have to escape them by means of a backslash (\), this can lead to conflicts +# with the commands \{ and \} for these it is advised to use the version @{ and +# @} or use a double escape (\\{ and \\}) + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice +# sources only. Doxygen will then generate output that is more tailored for that +# language. For instance, namespaces will be presented as modules, types will be +# separated into more groups, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_SLICE = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, +# Csharp (C#), C, C++, Lex, D, PHP, md (Markdown), Objective-C, Python, Slice, +# VHDL, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: +# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser +# tries to guess whether the code is fixed or free formatted code, this is the +# default for Fortran type files). For instance to make doxygen treat .inc files +# as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. When specifying no_extension you should add +# * to the FILE_PATTERNS. +# +# Note see also the list of default file extension mappings. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See https://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 5. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 0 + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = YES + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +# The NUM_PROC_THREADS specifies the number of threads doxygen is allowed to use +# during processing. When set to 0 doxygen will based this on the number of +# cores available in the system. You can set it explicitly to a value larger +# than 0 to get more control over the balance between CPU load and processing +# speed. At this moment only the input processing can be done using multiple +# threads. Since this is still an experimental feature the default is set to 1, +# which effectively disables parallel processing. Please report any issues you +# encounter. Generating dot graphs in parallel is controlled by the +# DOT_NUM_THREADS setting. +# Minimum value: 0, maximum value: 32, default value: 1. + +NUM_PROC_THREADS = 1 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual +# methods of a class will be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIV_VIRTUAL = NO + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = YES + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = YES + +# If this flag is set to YES, the name of an unnamed parameter in a declaration +# will be determined by the corresponding definition. By default unnamed +# parameters remain unnamed in the output. +# The default value is: YES. + +RESOLVE_UNNAMED_PARAMS = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# declarations. If set to NO, these declarations will be included in the +# documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = YES + +# With the correct setting of option CASE_SENSE_NAMES doxygen will better be +# able to match the capabilities of the underlying filesystem. In case the +# filesystem is case sensitive (i.e. it supports files in the same directory +# whose names only differ in casing), the option must be set to YES to properly +# deal with such files in case they appear in the input. For filesystems that +# are not case sensitive the option should be set to NO to properly deal with +# output files written for symbols that only differ in casing, such as for two +# classes, one named CLASS and the other named Class, and to also support +# references to files without having to specify the exact matching casing. On +# Windows (including Cygwin) and MacOS, users should typically set this option +# to NO, whereas on Linux or other Unix flavors it should typically be set to +# YES. +# The default value is: system dependent. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_HEADERFILE tag is set to YES then the documentation for a class +# will show which file needs to be included to use the class. +# The default value is: YES. + +SHOW_HEADERFILE = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = YES + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. See also section "Changing the +# layout of pages" for information. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as documenting some parameters in +# a documented function twice, or documenting parameters that don't exist or +# using markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# If WARN_IF_INCOMPLETE_DOC is set to YES, doxygen will warn about incomplete +# function parameter documentation. If set to NO, doxygen will accept that some +# parameters have no documentation without warning. +# The default value is: YES. + +WARN_IF_INCOMPLETE_DOC = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong parameter +# documentation, but not about the absence of documentation. If EXTRACT_ALL is +# set to YES then this flag will automatically be disabled. See also +# WARN_IF_INCOMPLETE_DOC +# The default value is: NO. + +WARN_NO_PARAMDOC = YES + +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS +# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but +# at the end of the doxygen process doxygen will return with a non-zero status. +# Possible values are: NO, YES and FAIL_ON_WARNINGS. +# The default value is: NO. + +WARN_AS_ERROR = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# See also: WARN_LINE_FORMAT +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# In the $text part of the WARN_FORMAT command it is possible that a reference +# to a more specific place is given. To make it easier to jump to this place +# (outside of doxygen) the user can define a custom "cut" / "paste" string. +# Example: +# WARN_LINE_FORMAT = "'vi $file +$line'" +# See also: WARN_FORMAT +# The default value is: at line $line of file $file. + +WARN_LINE_FORMAT = "at line $line of file $file" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). In case the file specified cannot be opened for writing the +# warning and error messages are written to standard error. When as file - is +# specified the warning and error messages are written to standard output +# (stdout). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. + +INPUT = + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: +# https://www.gnu.org/software/libiconv/) for the list of possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# Note the list of default checked file patterns might differ from the list of +# default file extension mappings. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.l, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, +# *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C +# comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, +# *.vhdl, *.ucf, *.qsf and *.ice. + +FILE_PATTERNS = *.cpp \ + *.c \ + *.h + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = GeneratedFiles \ + Submodules + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = */cmake-build*/* + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# ANamespace::AClass, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# entity all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see https://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a color-wheel, see +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use gray-scales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = YES + +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML +# documentation will contain a main index with vertical navigation menus that +# are dynamically created via JavaScript. If disabled, the navigation index will +# consists of multiple levels of tabs that are statically embedded in every HTML +# page. Disable this option to support browsers that do not have JavaScript, +# like the Qt help browser. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_MENUS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: +# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To +# create a documentation set, doxygen will generate a Makefile in the HTML +# output directory. Running make will produce the docset in that directory and +# running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy +# genXcode/_index.html for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag determines the URL of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDURL = + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# on Windows. In the beginning of 2021 Microsoft took the original page, with +# a.o. the download links, offline the HTML help workshop was already many years +# in maintenance mode). You can download the HTML help workshop from the web +# archives at Installation executable (see: +# http://web.archive.org/web/20160201063255/http://download.microsoft.com/downlo +# ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe). +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the main .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location (absolute path +# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to +# run qhelpgenerator on the generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine tune the look of the index (see "Fine-tuning the output"). As an +# example, the default style sheet generated by doxygen has an example that +# shows how to put an image at the root of the tree instead of the PROJECT_NAME. +# Since the tree basically has the same information as the tab index, you could +# consider setting DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = YES + +# When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the +# FULL_SIDEBAR option determines if the side bar is limited to only the treeview +# area (value NO) or if it should extend to the full height of the window (value +# YES). Setting this to YES gives a layout similar to +# https://docs.readthedocs.io with more room for contents, but less room for the +# project logo, title, and description. If either GENERATE_TREEVIEW or +# DISABLE_INDEX is set to NO, this option has no effect. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FULL_SIDEBAR = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# If the OBFUSCATE_EMAILS tag is set to YES, doxygen will obfuscate email +# addresses. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +OBFUSCATE_EMAILS = YES + +# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg +# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see +# https://inkscape.org) to generate formulas as SVG images instead of PNGs for +# the HTML output. These images will generally look nicer at scaled resolutions. +# Possible values are: png (the default) and svg (looks nicer but requires the +# pdf2svg or inkscape tool). +# The default value is: png. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FORMULA_FORMAT = png + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANSPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_TRANSPARENT = YES + +# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands +# to create new LaTeX commands to be used in formulas as building blocks. See +# the section "Including formulas" for details. + +FORMULA_MACROFILE = + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# https://www.mathjax.org) which uses client side JavaScript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# With MATHJAX_VERSION it is possible to specify the MathJax version to be used. +# Note that the different versions of MathJax have different requirements with +# regards to the different settings, so it is possible that also other MathJax +# settings have to be changed when switching between the different MathJax +# versions. +# Possible values are: MathJax_2 and MathJax_3. +# The default value is: MathJax_2. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_VERSION = MathJax_2 + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. For more details about the output format see MathJax +# version 2 (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) and MathJax version 3 +# (see: +# http://docs.mathjax.org/en/latest/web/components/output.html). +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility. This is the name for Mathjax version 2, for MathJax version 3 +# this will be translated into chtml), NativeMML (i.e. MathML. Only supported +# for NathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This +# is the name for Mathjax version 3, for MathJax version 2 this will be +# translated into HTML-CSS) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from https://www.mathjax.org before deployment. The default value is: +# - in case of MathJax version 2: https://cdn.jsdelivr.net/npm/mathjax@2 +# - in case of MathJax version 3: https://cdn.jsdelivr.net/npm/mathjax@3 +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = http://www.mathjax.org/mathjax + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# for MathJax version 2 (see https://docs.mathjax.org/en/v2.7-latest/tex.html +# #tex-and-latex-extensions): +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# For example for MathJax version 3 (see +# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html): +# MATHJAX_EXTENSIONS = ams +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /