From be91e3052fbf54e32721d73f1219b5bcd527b5a1 Mon Sep 17 00:00:00 2001 From: Samuel Cedarbaum Date: Sun, 7 May 2023 18:43:11 -0400 Subject: [PATCH] Handle vehicle GTFS entities --- api/admin.proto | 6 + api/public.proto | 157 ++ db/queries/stop_queries.sql | 50 +- db/queries/trip_queries.sql | 37 +- db/queries/vehicle_queries.sql | 95 + db/schema/005_vehicle_updates.sql | 35 + docs/src/api/admin.md | 1 + docs/src/api/public_endpoints.md | 89 + docs/src/api/public_resources.md | 76 +- go.mod | 2 +- go.sum | 4 +- internal/convert/convert.go | 92 +- internal/db/dbtesting/dbtesting.go | 4 +- internal/db/dbwrappers/dbwrappers.go | 50 +- internal/gen/api/admin.pb.go | 480 ++-- internal/gen/api/public.pb.go | 2470 ++++++++++++++------- internal/gen/api/public.pb.gw.go | 244 ++ internal/gen/api/public_grpc.pb.go | 92 + internal/gen/db/batch.go | 2 +- internal/gen/db/models.go | 13 +- internal/gen/db/querier.go | 13 +- internal/gen/db/stop_queries.sql.go | 58 +- internal/gen/db/trip_queries.sql.go | 147 +- internal/gen/db/vehicle_queries.sql.go | 486 ++++ internal/public/endpoints/context.go | 3 + internal/public/endpoints/stop.go | 15 +- internal/public/endpoints/trip.go | 22 +- internal/public/endpoints/vehicle.go | 207 ++ internal/public/public.go | 10 +- internal/public/reference/reference.go | 6 +- internal/server/server.go | 25 +- internal/servicemaps/servicemaps.go | 2 +- internal/update/realtime/realtime.go | 212 +- internal/update/realtime/realtime_test.go | 662 +++++- systems/us-ny-nycbus.yaml | 18 +- tests/endtoend/Dockerfile | 1 + tests/endtoend/conftest.py | 5 +- tests/endtoend/test_vehicles.py | 294 +++ transiter.go | 30 +- 39 files changed, 5008 insertions(+), 1207 deletions(-) create mode 100644 db/queries/vehicle_queries.sql create mode 100644 db/schema/005_vehicle_updates.sql create mode 100644 internal/gen/db/vehicle_queries.sql.go create mode 100644 internal/public/endpoints/vehicle.go create mode 100644 tests/endtoend/test_vehicles.py diff --git a/api/admin.proto b/api/admin.proto index 23baaa20..6d9ed503 100644 --- a/api/admin.proto +++ b/api/admin.proto @@ -293,6 +293,12 @@ message GtfsRealtimeOptions { // This should not be used for systems where a trip can call at the same // stop multiple times. bool reassign_stop_sequences = 4; + + // If true, only process entities in a feed if the message contains + // the full entity. This is useful for cases where there are multiple + // feeds for the same system, and some feeds contain only partial + // information about entities. + bool only_process_full_entities = 5; } // Description of the configuration for a collection of service maps. diff --git a/api/public.proto b/api/public.proto index e3cd4e69..2234a6ed 100644 --- a/api/public.proto +++ b/api/public.proto @@ -246,6 +246,28 @@ service Public { }; } + // List vehicles + // + // `GET /systems//vehicles` + // + // List all feeds for a system. + rpc ListVehicles(ListVehiclesRequest) returns (ListVehiclesReply) { + option (google.api.http) = { + get: "/systems/{system_id}/vehicles" + }; + } + + // Get vehicle + // + // `GET /systems//vehicles/` + // + // Get a vehicle in a system by its ID. + rpc GetVehicle(GetVehicleRequest) returns (Vehicle) { + option (google.api.http) = { + get: "/systems/{system_id}/vehicles/{vehicle_id}" + }; + } + } // Request payload for the entrypoint endpoint. @@ -566,6 +588,67 @@ message ListTransfersReply { repeated Transfer transfers = 1; } +message ListVehiclesRequest { + // ID of the system for which to list vehicles. + string system_id = 1; + + enum SearchMode { + // Return a paginated list of vehicles sorted by vehicle ID. + ID = 0; + // Return all vehicles within max_distance of (latitude, longitude), sorted by the distance. + DISTANCE = 1; + } + // The type of search to perform when listing vehicles. + optional SearchMode search_mode = 2; + + // If true, only return vehicles whose IDs are specified in the repeated `id` field. + // Only supported when the search mode is ID. + bool only_return_specified_ids = 3; + + // IDs to return if `only_return_specified_ids` is set to true. It is an error to + // populate this field if `only_return_specified_ids` is false. + // Only supported when the search mode is ID. + repeated string id = 4; + + // ID of the first vehicle to return. If not set, the vehicle with the smallest ID will be first. + // Only supported when the search mode is ID. + optional string first_id = 5; + + // Maximum number of vehicles to return. + // This is supported in all search modes. + // For performance reasons, if it is larger than 100 it is rounded down to 100. + optional int32 limit = 6; + + // The maximum distance in kilometers that a vehicle must be from + // latitude, longitude to be listed when using DISTANCE search mode. + optional double max_distance = 7; + + // The latitude relative to the returned vehicles when using DISTANCE search mode. + optional double latitude = 8; + + // The longitude relative to the returned vehicles when using DISTANCE search mode. + optional double longitude = 9; +} + +message ListVehiclesReply { + // List of vehicles. + repeated Vehicle vehicles = 1; + + // ID of the next vehicle to return, if there are more results. + optional string next_id = 2; +} + +message GetVehicleRequest { + // ID of the system the vehicle is in. + // + // This is a URL parameter in the HTTP API. + string system_id = 1; + // ID of the vehicle. + // + // This is a URL parameter in the HTTP API. + string vehicle_id = 2; +} + // The System resource. message System { // ID of the system as specified in the install request. @@ -794,10 +877,84 @@ message Trip { } } +// The Vehicle resource. +// +// This resource corresponds to the [vehicle position type in the GTFS static +// specification](https://developers.google.com/transit/gtfs-realtime/reference#message-vehicleposition). message Vehicle { + // A unique ID for the vehicle. + string id = 1; + + // A reference to the vehicle's trip. + optional Trip.Reference trip = 2; + + // The vehicle's current latitude. + optional double latitude = 3; + + // The vehicle's current longitude. + optional double longitude = 4; + + // The vehicle's current bearing. + optional float bearing = 5; + + // The vehicle's current odometer reading. + optional double odometer = 6; + + // The vehicle's current speed. + optional float speed = 7; + + // The stop sequence index of the vehicle's current stop. + optional int32 stop_sequence = 8; + + // A reference to the vehicle's current stop. + optional Stop.Reference stop = 9; + + // Corresponds to [VehicleStopStatus](https://developers.google.com/ + // transit/gtfs-realtime/reference#enum-vehiclestopstatus). + enum CurrentStatus { + INCOMING_AT = 0; + STOPPED_AT = 1; + IN_TRANSIT_TO = 2; + } + // The vehicle's current status. + optional CurrentStatus current_status = 10; + + // The timestamp of the last update to the vehicle's position. + optional int64 updated_at = 11; + + // Corresponds to [CongestionLevel](https://developers.google.com/ + // transit/gtfs-realtime/reference#enum-congestionlevel). + enum CongestionLevel { + UNKNOWN_CONGESTION_LEVEL = 0; + RUNNING_SMOOTHLY = 1; + STOP_AND_GO = 2; + CONGESTION = 3; + SEVERE_CONGESTION = 4; + } + // The vehicle's current congestion level. + CongestionLevel congestion_level = 12; + + // Corresponds to [OccupancyStatus](https://developers.google.com/ + // transit/gtfs-realtime/reference#enum-occupancystatus). + enum OccupancyStatus { + EMPTY = 0; + MANY_SEATS_AVAILABLE = 1; + FEW_SEATS_AVAILABLE = 2; + STANDING_ROOM_ONLY = 3; + CRUSHED_STANDING_ROOM_ONLY = 4; + FULL = 5; + NOT_ACCEPTING_PASSENGERS = 6; + } + // The vehicle's current occupancy status. + optional OccupancyStatus occupancy_status = 13; + + // The percentage of seats occupied. + optional int32 occupancy_percentage = 14; + // Reference is the reference type for the vehicle resource. message Reference { string id = 1; + Resource resource = 2; } } diff --git a/db/queries/stop_queries.sql b/db/queries/stop_queries.sql index c97e3246..2f101f6a 100644 --- a/db/queries/stop_queries.sql +++ b/db/queries/stop_queries.sql @@ -19,8 +19,8 @@ UPDATE stop SET code = sqlc.arg(code), description = sqlc.arg(description), platform_code = sqlc.arg(platform_code), - timezone = sqlc.arg(timezone), - type = sqlc.arg(type), + timezone = sqlc.arg(timezone), + type = sqlc.arg(type), wheelchair_boarding = sqlc.arg(wheelchair_boarding), zone_id = sqlc.arg(zone_id), parent_stop_pk = NULL @@ -35,7 +35,7 @@ WHERE -- name: DeleteStaleStops :exec DELETE FROM stop -WHERE +WHERE stop.feed_pk = sqlc.arg(feed_pk) AND NOT stop.pk = ANY(sqlc.arg(updated_stop_pks)::bigint[]); @@ -52,7 +52,7 @@ LIMIT sqlc.arg(num_stops); -- name: ListStops_Geographic :many WITH distance AS ( - SELECT + SELECT pk stop_pk, (6371 * acos(cos(radians(latitude)) * cos(radians(sqlc.arg(latitude)::numeric)) * cos(radians(sqlc.arg(longitude)::numeric) - radians(longitude)) + sin(radians(latitude)) * sin(radians(sqlc.arg(latitude)::numeric)))) val FROM stop @@ -71,7 +71,13 @@ SELECT stop.* FROM stop AND stop.id = sqlc.arg(stop_id); -- name: ListTripStopTimesByStops :many -SELECT trip_stop_time.*, trip.*, vehicle.id vehicle_id FROM trip_stop_time +SELECT trip_stop_time.*, + trip.*, vehicle.id vehicle_id, + vehicle.latitude vehicle_latitude, + vehicle.longitude vehicle_longitude, + vehicle.bearing vehicle_bearing, + vehicle.updated_at vehicle_updated_at + FROM trip_stop_time INNER JOIN trip ON trip_stop_time.trip_pk = trip.pk LEFT JOIN vehicle ON vehicle.trip_pk = trip.pk WHERE trip_stop_time.stop_pk = ANY(sqlc.arg(stop_pks)::bigint[]) @@ -90,29 +96,29 @@ FROM stop WHERE stop.parent_stop_pk = ANY(sqlc.arg(stop_pks)::bigint[]); -- name: MapStopIDAndPkToStationPk :many -WITH RECURSIVE +WITH RECURSIVE ancestor AS ( - SELECT - id stop_id, + SELECT + id stop_id, pk stop_pk, - pk station_pk, + pk station_pk, parent_stop_pk, - (type = 'STATION') is_station + (type = 'STATION') is_station FROM stop WHERE stop.system_pk = sqlc.arg(system_pk) AND ( NOT sqlc.arg(filter_by_stop_pk)::bool OR stop.pk = ANY(sqlc.arg(stop_pks)::bigint[]) ) - UNION - SELECT + UNION + SELECT child.stop_id stop_id, child.stop_pk stop_pk, - parent.pk station_pk, - parent.parent_stop_pk, - (parent.type = 'STATION') is_station - FROM stop parent - INNER JOIN ancestor child + parent.pk station_pk, + parent.parent_stop_pk, + (parent.type = 'STATION') is_station + FROM stop parent + INNER JOIN ancestor child ON child.parent_stop_pk = parent.pk AND NOT child.is_station ) @@ -123,17 +129,17 @@ SELECT stop_id, stop_pk, station_pk -- name: MapStopPkToDescendentPks :many WITH RECURSIVE descendent AS ( - SELECT + SELECT stop.pk root_stop_pk, stop.pk descendent_stop_pk FROM stop WHERE stop.pk = ANY(sqlc.arg(stop_pks)::bigint[]) - UNION - SELECT + UNION + SELECT descendent.root_stop_pk root_stop_pk, child.pk descendent_stop_pk - FROM stop child - INNER JOIN descendent + FROM stop child + INNER JOIN descendent ON child.parent_stop_pk = descendent.descendent_stop_pk ) SELECT root_stop_pk, descendent_stop_pk FROM descendent; diff --git a/db/queries/trip_queries.sql b/db/queries/trip_queries.sql index 2bf3253d..76f71e42 100644 --- a/db/queries/trip_queries.sql +++ b/db/queries/trip_queries.sql @@ -14,12 +14,33 @@ SELECT lss.trip_pk, stop.pk destination_pk ON trip_stop_time.stop_pk = stop.pk; -- name: ListTrips :many -SELECT * FROM trip +SELECT trip.*, + vehicle.id as vehicle_id, + vehicle.latitude as vehicle_latitude, + vehicle.longitude as vehicle_longitude, + vehicle.bearing as vehicle_bearing, + vehicle.updated_at as vehicle_updated_at +FROM trip +LEFT JOIN vehicle ON trip.pk = vehicle.trip_pk WHERE route_pk = ANY(sqlc.arg(route_pks)::bigint[]) ORDER BY route_pk, id; +-- name: ListTripPksInSystem :many +SELECT trip.id, trip.pk +FROM trip + INNER JOIN feed ON trip.feed_pk = feed.pk +WHERE trip.id = ANY(sqlc.arg(trip_ids)::text[]) + AND feed.system_pk = sqlc.arg(system_pk); + -- name: GetTrip :one -SELECT * FROM trip +SELECT trip.*, + vehicle.id as vehicle_id, + vehicle.latitude as vehicle_latitude, + vehicle.longitude as vehicle_longitude, + vehicle.bearing as vehicle_bearing, + vehicle.updated_at as vehicle_updated_at +FROM trip +LEFT JOIN vehicle ON trip.pk = vehicle.trip_pk WHERE trip.id = sqlc.arg(trip_id) AND trip.route_pk = sqlc.arg(route_pk); @@ -38,7 +59,7 @@ VALUES RETURNING pk; -- name: UpdateTrip :batchexec -UPDATE trip SET +UPDATE trip SET feed_pk = sqlc.arg(feed_pk), direction_id = sqlc.arg(direction_id), started_at = sqlc.arg(started_at), @@ -90,7 +111,15 @@ WHERE pk = ANY(sqlc.arg(pks)::bigint[]); -- name: DeleteStaleTrips :many DELETE FROM trip -WHERE +WHERE trip.feed_pk = sqlc.arg(feed_pk) AND NOT trip.pk = ANY(sqlc.arg(updated_trip_pks)::bigint[]) RETURNING trip.route_pk; + +-- name: MapTripIDToPkInSystem :many +SELECT trip.id, trip.pk +FROM trip + INNER JOIN feed ON trip.feed_pk = feed.pk +WHERE trip.id = ANY(sqlc.arg(trip_ids)::text[]) + AND feed.system_pk = sqlc.arg(system_pk) +FOR UPDATE; diff --git a/db/queries/vehicle_queries.sql b/db/queries/vehicle_queries.sql new file mode 100644 index 00000000..28cca638 --- /dev/null +++ b/db/queries/vehicle_queries.sql @@ -0,0 +1,95 @@ +-- name: InsertVehicle :exec +INSERT INTO vehicle + (id, system_pk, trip_pk, label, license_plate, current_status, latitude, longitude, bearing, odometer, speed, congestion_level, updated_at, current_stop_pk, current_stop_sequence, occupancy_status, feed_pk, occupancy_percentage) +VALUES + (sqlc.arg(id), sqlc.arg(system_pk), sqlc.arg(trip_pk), sqlc.arg(label), sqlc.arg(license_plate), sqlc.arg(current_status), sqlc.arg(latitude), sqlc.arg(longitude), sqlc.arg(bearing), sqlc.arg(odometer), sqlc.arg(speed), sqlc.arg(congestion_level), sqlc.arg(updated_at), sqlc.arg(current_stop_pk), sqlc.arg(current_stop_sequence), sqlc.arg(occupancy_status), sqlc.arg(feed_pk), sqlc.arg(occupancy_percentage)); + +-- name: UpdateVehicle :exec +UPDATE vehicle +SET trip_pk = sqlc.arg(trip_pk), + label = sqlc.arg(label), + license_plate = sqlc.arg(license_plate), + current_status = sqlc.arg(current_status), + latitude = sqlc.arg(latitude), + longitude = sqlc.arg(longitude), + bearing = sqlc.arg(bearing), + odometer = sqlc.arg(odometer), + speed = sqlc.arg(speed), + congestion_level = sqlc.arg(congestion_level), + updated_at = sqlc.arg(updated_at), + current_stop_pk = sqlc.arg(current_stop_pk), + current_stop_sequence = sqlc.arg(current_stop_sequence), + occupancy_status = sqlc.arg(occupancy_status), + feed_pk = sqlc.arg(feed_pk), + occupancy_percentage = sqlc.arg(occupancy_percentage) +WHERE vehicle.pk = sqlc.arg(pk); + +-- name: ListVehicles :many +SELECT vehicle.*, + stop.id as stop_id, + stop.name as stop_name, + trip.id as trip_id, + trip.direction_id as trip_direction_id, + route.id as route_id, + route.color as route_color +FROM vehicle +LEFT JOIN stop ON vehicle.current_stop_pk = stop.pk +LEFT JOIN trip ON vehicle.trip_pk = trip.pk +LEFT JOIN route ON trip.route_pk = route.pk +WHERE vehicle.system_pk = sqlc.arg(system_pk) + AND vehicle.id >= sqlc.arg(first_vehicle_id) + AND ( + NOT sqlc.arg(only_return_specified_ids)::bool OR + vehicle.id = ANY(sqlc.arg(vehicle_ids)::text[]) + ) +ORDER BY vehicle.id +LIMIT sqlc.arg(num_vehicles); + +-- name: ListVehicles_Geographic :many +WITH distance AS ( + SELECT + pk vehicle_pk, + (6371 * acos(cos(radians(latitude)) * cos(radians(sqlc.arg(latitude)::numeric)) * cos(radians(sqlc.arg(longitude)::numeric) - radians(longitude)) + sin(radians(latitude)) * sin(radians(sqlc.arg(latitude)::numeric)))) val + FROM vehicle + WHERE vehicle.system_pk = sqlc.arg(system_pk) AND latitude IS NOT NULL AND longitude IS NOT NULL +) +SELECT vehicle.*, + stop.id as stop_id, + stop.name as stop_name, + trip.id as trip_id, + trip.direction_id as trip_direction_id, + route.id as route_id, + route.color as route_color +FROM vehicle +INNER JOIN distance ON vehicle.pk = distance.vehicle_pk +AND distance.val <= sqlc.arg(max_distance)::numeric +LEFT JOIN stop ON vehicle.current_stop_pk = stop.pk +LEFT JOIN trip ON vehicle.trip_pk = trip.pk +LEFT JOIN route ON trip.route_pk = route.pk +ORDER BY distance.val +LIMIT sqlc.arg(num_vehicles); + +-- name: GetVehicle :one +SELECT vehicle.*, + stop.id as stop_id, + stop.name as stop_name, + trip.id as trip_id, + trip.direction_id as trip_direction_id, + route.id as route_id, + route.color as route_color +FROM vehicle +LEFT JOIN stop ON vehicle.current_stop_pk = stop.pk +LEFT JOIN trip ON vehicle.trip_pk = trip.pk +LEFT JOIN route ON trip.route_pk = route.pk +WHERE vehicle.system_pk = sqlc.arg(system_pk) AND vehicle.id = sqlc.arg(vehicle_id); + +-- name: ListVehicleUniqueColumns :many +SELECT id, pk, trip_pk FROM vehicle +WHERE id = ANY(sqlc.arg(vehicle_ids)::text[]) +AND system_pk = sqlc.arg(system_pk); + +-- name: DeleteStaleVehicles :exec +DELETE FROM vehicle +WHERE + feed_pk = sqlc.arg(feed_pk) + AND NOT id = ANY(sqlc.arg(active_vehicle_ids)::text[]); diff --git a/db/schema/005_vehicle_updates.sql b/db/schema/005_vehicle_updates.sql new file mode 100644 index 00000000..f47be768 --- /dev/null +++ b/db/schema/005_vehicle_updates.sql @@ -0,0 +1,35 @@ +-- +goose Up + +ALTER TABLE vehicle ALTER COLUMN current_status DROP NOT NULL; +ALTER TABLE vehicle ALTER COLUMN occupancy_status DROP NOT NULL; + +ALTER TABLE vehicle +ALTER COLUMN latitude +TYPE numeric(9, 6) +USING latitude::numeric(9, 6); + +ALTER TABLE vehicle +ALTER COLUMN longitude +TYPE numeric(9, 6) +USING longitude::numeric(9, 6); + +ALTER TABLE vehicle +ALTER COLUMN bearing +TYPE real +USING latitude::real; + +ALTER TABLE vehicle +ALTER COLUMN speed +TYPE real +USING longitude::real; + +ALTER TABLE vehicle +ADD COLUMN occupancy_percentage integer; + +ALTER TABLE vehicle DROP CONSTRAINT fk_vehicle_current_stop_pk; +ALTER TABLE vehicle + ADD CONSTRAINT fk_vehicle_current_stop_pk FOREIGN KEY (current_stop_pk) REFERENCES stop(pk) ON DELETE SET NULL; + +ALTER TABLE vehicle DROP CONSTRAINT fk_vehicle_trip_pk; +ALTER TABLE vehicle + ADD CONSTRAINT fk_vehicle_trip_pk FOREIGN KEY (trip_pk) REFERENCES trip(pk) ON DELETE SET NULL; diff --git a/docs/src/api/admin.md b/docs/src/api/admin.md index 262fa7ee..68d3775c 100644 --- a/docs/src/api/admin.md +++ b/docs/src/api/admin.md @@ -456,6 +456,7 @@ Message describing additional options for the GTFS realtime feeds. | nyct_trips_options | [GtfsRealtimeOptions.NyctTripsOptions](admin.md#GtfsRealtimeOptions.NyctTripsOptions) | | nyct_alerts_options | [GtfsRealtimeOptions.NyctAlertsOptions](admin.md#GtfsRealtimeOptions.NyctAlertsOptions) | | reassign_stop_sequences | bool | If true, stop sequences in the GTFS realtime feed data are ignored, and alternative stop sequences are generated and assigned by Transiter. This setting is designed for buggy GTFS realtime feeds in which stop sequences (incorrectly) change between updates. In many cases Transiter is able to generate stop sequences that are correct and stable across updates.

This should not be used for systems where a trip can call at the same stop multiple times. +| only_process_full_entities | bool | If true, only process entities in a feed if the message contains the full entity. This is useful for cases where there are multiple feeds for the same system, and some feeds contain only partial information about entities. diff --git a/docs/src/api/public_endpoints.md b/docs/src/api/public_endpoints.md index f03b855f..6d5440a5 100644 --- a/docs/src/api/public_endpoints.md +++ b/docs/src/api/public_endpoints.md @@ -623,6 +623,95 @@ Request payload for the get feed endpoint. ### Response type: [Feed](public_resources.md#Feed) +## List vehicles + +`GET /systems//vehicles` + +List all feeds for a system. + +### Request type: ListVehiclesRequest + + + + + +| Field | Type | Description | +| ----- | ---- | ----------- | +| system_id | string | ID of the system for which to list vehicles. +| search_mode | [ListVehiclesRequest.SearchMode](public_resources.md#ListVehiclesRequest.SearchMode) | The type of search to perform when listing vehicles. +| only_return_specified_ids | bool | If true, only return vehicles whose IDs are specified in the repeated `id` field. Only supported when the search mode is ID. +| id | string | IDs to return if `only_return_specified_ids` is set to true. It is an error to populate this field if `only_return_specified_ids` is false. Only supported when the search mode is ID. +| first_id | string | ID of the first vehicle to return. If not set, the vehicle with the smallest ID will be first. Only supported when the search mode is ID. +| limit | int32 | Maximum number of vehicles to return. This is supported in all search modes. For performance reasons, if it is larger than 100 it is rounded down to 100. +| max_distance | double | The maximum distance in kilometers that a vehicle must be from latitude, longitude to be listed when using DISTANCE search mode. +| latitude | double | The latitude relative to the returned vehicles when using DISTANCE search mode. +| longitude | double | The longitude relative to the returned vehicles when using DISTANCE search mode. + + + + + + +#### ListVehiclesRequest.SearchMode + + + + + + +| Name | Number | Description | +| ---- | ------ | ----------- | +| ID | 0 | Return a paginated list of vehicles sorted by vehicle ID. | +| DISTANCE | 1 | Return all vehicles within max_distance of (latitude, longitude), sorted by the distance. | + + + + + +### Response type: ListVehiclesReply + + + + + +| Field | Type | Description | +| ----- | ---- | ----------- | +| vehicles | [Vehicle](public_resources.md#Vehicle) | List of vehicles. +| next_id | string | ID of the next vehicle to return, if there are more results. + + + + + + + + +## Get vehicle + +`GET /systems//vehicles/` + +Get a vehicle in a system by its ID. + +### Request type: GetVehicleRequest + + + + + +| Field | Type | Description | +| ----- | ---- | ----------- | +| system_id | string | ID of the system the vehicle is in.

This is a URL parameter in the HTTP API. +| vehicle_id | string | ID of the vehicle.

This is a URL parameter in the HTTP API. + + + + + + + + +### Response type: [Vehicle](public_resources.md#Vehicle) + diff --git a/docs/src/api/public_resources.md b/docs/src/api/public_resources.md index 7ff32936..0459030a 100644 --- a/docs/src/api/public_resources.md +++ b/docs/src/api/public_resources.md @@ -765,14 +765,87 @@ Reference is the reference type for the trip resource. ## Vehicle +The Vehicle resource. +This resource corresponds to the [vehicle position type in the GTFS static +specification](https://developers.google.com/transit/gtfs-realtime/reference#message-vehicleposition). -No fields. +| Field | Type | Description | +| ----- | ---- | ----------- | +| id | string | A unique ID for the vehicle. +| trip | [Trip.Reference](public_resources.md#Trip.Reference) | A reference to the vehicle's trip. +| latitude | double | The vehicle's current latitude. +| longitude | double | The vehicle's current longitude. +| bearing | float | The vehicle's current bearing. +| odometer | double | The vehicle's current odometer reading. +| speed | float | The vehicle's current speed. +| stop_sequence | int32 | The stop sequence index of the vehicle's current stop. +| stop | [Stop.Reference](public_resources.md#Stop.Reference) | A reference to the vehicle's current stop. +| current_status | [Vehicle.CurrentStatus](public_resources.md#Vehicle.CurrentStatus) | The vehicle's current status. +| updated_at | int64 | The timestamp of the last update to the vehicle's position. +| congestion_level | [Vehicle.CongestionLevel](public_resources.md#Vehicle.CongestionLevel) | The vehicle's current congestion level. +| occupancy_status | [Vehicle.OccupancyStatus](public_resources.md#Vehicle.OccupancyStatus) | The vehicle's current occupancy status. +| occupancy_percentage | int32 | The percentage of seats occupied. + + + + + + +#### Vehicle.CongestionLevel + +Corresponds to [CongestionLevel](https://developers.google.com/ +transit/gtfs-realtime/reference#enum-congestionlevel). + + + + +| Name | Number | Description | +| ---- | ------ | ----------- | +| UNKNOWN_CONGESTION_LEVEL | 0 | | +| RUNNING_SMOOTHLY | 1 | | +| STOP_AND_GO | 2 | | +| CONGESTION | 3 | | +| SEVERE_CONGESTION | 4 | | + + + +#### Vehicle.CurrentStatus + +Corresponds to [VehicleStopStatus](https://developers.google.com/ +transit/gtfs-realtime/reference#enum-vehiclestopstatus). + +| Name | Number | Description | +| ---- | ------ | ----------- | +| INCOMING_AT | 0 | | +| STOPPED_AT | 1 | | +| IN_TRANSIT_TO | 2 | | + + + +#### Vehicle.OccupancyStatus + +Corresponds to [OccupancyStatus](https://developers.google.com/ +transit/gtfs-realtime/reference#enum-occupancystatus). + + + + +| Name | Number | Description | +| ---- | ------ | ----------- | +| EMPTY | 0 | | +| MANY_SEATS_AVAILABLE | 1 | | +| FEW_SEATS_AVAILABLE | 2 | | +| STANDING_ROOM_ONLY | 3 | | +| CRUSHED_STANDING_ROOM_ONLY | 4 | | +| FULL | 5 | | +| NOT_ACCEPTING_PASSENGERS | 6 | | + #### Vehicle.Reference @@ -784,6 +857,7 @@ Reference is the reference type for the vehicle resource. | Field | Type | Description | | ----- | ---- | ----------- | | id | string | +| resource | [Resource](public_resources.md#Resource) | diff --git a/go.mod b/go.mod index 7db5246f..0d3f47c2 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.2 github.com/jackc/pgx/v5 v5.3.1 github.com/jackc/tern/v2 v2.0.1 - github.com/jamespfennell/gtfs v0.1.13 + github.com/jamespfennell/gtfs v0.1.14 github.com/kyleconroy/sqlc v1.17.2 github.com/prometheus/client_golang v1.14.0 github.com/pseudomuto/protoc-gen-doc v1.5.1 diff --git a/go.sum b/go.sum index 88777bf2..fcd8fb53 100644 --- a/go.sum +++ b/go.sum @@ -84,8 +84,8 @@ github.com/jackc/puddle/v2 v2.2.0 h1:RdcDk92EJBuBS55nQMMYFXTxwstHug4jkhT5pq8VxPk github.com/jackc/puddle/v2 v2.2.0/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jackc/tern/v2 v2.0.1 h1:2J05jlmYFsNQe9rGsqoNs0+6eDm3iJns8RQb6DJl1V8= github.com/jackc/tern/v2 v2.0.1/go.mod h1:4cpqN/grjWYeRWcKXah5YGoviJKJuoqNLoORKLumoG0= -github.com/jamespfennell/gtfs v0.1.13 h1:KhwAdVahDY9Nhvllddv0df1OVliJ+0ZH3G4jrvEQ1xE= -github.com/jamespfennell/gtfs v0.1.13/go.mod h1:R92JynGzDyrjrFLQ4ye5NFegBYAigK/JFY2oTKNLHfU= +github.com/jamespfennell/gtfs v0.1.14 h1:3woWtmXHFh5HMplaWpT568JPq2zkiiLyraXRe0hdEHg= +github.com/jamespfennell/gtfs v0.1.14/go.mod h1:R92JynGzDyrjrFLQ4ye5NFegBYAigK/JFY2oTKNLHfU= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= diff --git a/internal/convert/convert.go b/internal/convert/convert.go index aef1957b..738ed4be 100644 --- a/internal/convert/convert.go +++ b/internal/convert/convert.go @@ -41,6 +41,20 @@ func SQLNullString(t pgtype.Text) *string { return &t.String } +func SQLNullFloat4(t pgtype.Float4) *float32 { + if !t.Valid { + return nil + } + return &t.Float32 +} + +func SQLNullFloat8(t pgtype.Float8) *float64 { + if !t.Valid { + return nil + } + return &t.Float64 +} + func SQLNullFloat64(t sql.NullFloat64) *float64 { if !t.Valid { return nil @@ -69,6 +83,13 @@ func NullInt32(t *int32) pgtype.Int4 { return pgtype.Int4{Valid: true, Int32: *t} } +func NullUInt32ToSigned(t *uint32) pgtype.Int4 { + if t == nil { + return pgtype.Int4{} + } + return pgtype.Int4{Valid: true, Int32: int32(*t)} +} + func NullInt64(t *int64) pgtype.Int8 { if t == nil { return pgtype.Int8{} @@ -76,6 +97,13 @@ func NullInt64(t *int64) pgtype.Int8 { return pgtype.Int8{Valid: true, Int64: *t} } +func NullFloat32(t *float32) pgtype.Float4 { + if t == nil { + return pgtype.Float4{} + } + return pgtype.Float4{Valid: true, Float32: *t} +} + func NullFloat64(t *float64) pgtype.Float8 { if t == nil { return pgtype.Float8{} @@ -104,7 +132,7 @@ func SQLNullBool(t pgtype.Bool) *bool { return &t.Bool } -func Gps(f *float64) pgtype.Numeric { +func Gps[T float32 | float64](f *T) pgtype.Numeric { if f == nil { return pgtype.Numeric{} } @@ -216,6 +244,33 @@ func RouteType(t string) api.Route_Type { return api.Route_UNKNOWN } +func NullApiCurrentStatus(t pgtype.Text) *api.Vehicle_CurrentStatus { + if !t.Valid { + return nil + } + if i, ok := api.Vehicle_CurrentStatus_value[t.String]; ok { + return api.Vehicle_CurrentStatus(i).Enum() + } + return nil +} + +func ApiCongestionLevel(t string) api.Vehicle_CongestionLevel { + if i, ok := api.Vehicle_CongestionLevel_value[t]; ok { + return api.Vehicle_CongestionLevel(i) + } + return api.Vehicle_UNKNOWN_CONGESTION_LEVEL +} + +func NullApiOccupancyStatus(t pgtype.Text) *api.Vehicle_OccupancyStatus { + if !t.Valid { + return nil + } + if i, ok := api.Vehicle_OccupancyStatus_value[t.String]; ok { + return api.Vehicle_OccupancyStatus(i).Enum() + } + return nil +} + func GtfsRealtimeExtension(in *api.GtfsRealtimeOptions) (extensions.Extension, error) { if in == nil { in = &api.GtfsRealtimeOptions{} @@ -226,7 +281,7 @@ func GtfsRealtimeExtension(in *api.GtfsRealtimeOptions) (extensions.Extension, e case api.GtfsRealtimeOptions_NYCT_TRIPS: inOpts := in.GetNyctTripsOptions() return nycttrips.Extension(nycttrips.ExtensionOpts{ - FilterStaleUnassignedTrips: inOpts.GetFilterStaleUnassignedTrips(), + FilterStaleUnassignedTrips: inOpts.GetFilterStaleUnassignedTrips(), PreserveMTrainPlatformsInBushwick: inOpts.GetPreserveMTrainPlatformsInBushwick(), }), nil case api.GtfsRealtimeOptions_NYCT_ALERTS: @@ -254,3 +309,36 @@ func GtfsRealtimeExtension(in *api.GtfsRealtimeOptions) (extensions.Extension, e return nil, fmt.Errorf("unknown extension %s", in.Extension) } } + +func NullVehicleCurrentStatus(currentStatus *gtfs.CurrentStatus) pgtype.Text { + if currentStatus == nil { + return pgtype.Text{} + } + + return pgtype.Text{ + Valid: true, + String: currentStatus.String(), + } +} + +func NullCongestionLevel(congestionLevel *gtfs.CongestionLevel) string { + if congestionLevel == nil { + // UNKNOWN_CONGESTION_LEVEL + return CongestionLevel(0) + } + return CongestionLevel(*congestionLevel) +} + +func CongestionLevel(congestionLevel gtfs.CongestionLevel) string { + return congestionLevel.String() +} + +func NullOccupancyStatus(occupancyStatus *gtfs.OccupancyStatus) pgtype.Text { + if occupancyStatus == nil { + return pgtype.Text{} + } + return pgtype.Text{ + Valid: true, + String: occupancyStatus.String(), + } +} diff --git a/internal/db/dbtesting/dbtesting.go b/internal/db/dbtesting/dbtesting.go index decbdb7e..1a1b4a38 100644 --- a/internal/db/dbtesting/dbtesting.go +++ b/internal/db/dbtesting/dbtesting.go @@ -223,7 +223,7 @@ type StopTime struct { Arrival time.Time } -func (r *Route) NewTrip(id string, stopTimes []StopTime) db.Trip { +func (r *Route) NewTrip(id string, stopTimes []StopTime) db.GetTripRow { var pk int64 trip := insertAndGet( r.s.q, id, @@ -236,7 +236,7 @@ func (r *Route) NewTrip(id string, stopTimes []StopTime) db.Trip { }) return err }, - func() (db.Trip, error) { + func() (db.GetTripRow, error) { return r.s.q.GetTrip(context.Background(), db.GetTripParams{ RoutePk: r.Data.Pk, TripID: id, diff --git a/internal/db/dbwrappers/dbwrappers.go b/internal/db/dbwrappers/dbwrappers.go index d8ab98a1..9ac99286 100644 --- a/internal/db/dbwrappers/dbwrappers.go +++ b/internal/db/dbwrappers/dbwrappers.go @@ -124,17 +124,39 @@ func MapRouteIDToPkInSystem(ctx context.Context, querier db.Querier, systemPk in return result, nil } +func MapTripIDToPkInSystem(ctx context.Context, querier db.Querier, systemPk int64, tripIDs ...[]string) (map[string]int64, error) { + result := map[string]int64{} + var queryTripIDs []string + if len(tripIDs) > 0 { + queryTripIDs = tripIDs[0] + if len(queryTripIDs) == 0 { + return result, nil + } + } + rows, err := querier.MapTripIDToPkInSystem(ctx, db.MapTripIDToPkInSystemParams{ + SystemPk: systemPk, + TripIds: queryTripIDs, + }) + if err != nil { + return nil, err + } + for _, row := range rows { + result[row.ID] = row.Pk + } + return result, nil +} + type TripUID struct { ID string RoutePk int64 } -func ListTripsForUpdate(ctx context.Context, querier db.Querier, routePks []int64) (map[TripUID]db.Trip, error) { +func ListTripsForUpdate(ctx context.Context, querier db.Querier, systemPk int64, routePks []int64) (map[TripUID]db.ListTripsRow, error) { rows, err := querier.ListTrips(ctx, routePks) if err != nil { return nil, err } - m := map[TripUID]db.Trip{} + m := map[TripUID]db.ListTripsRow{} for _, row := range rows { uid := TripUID{RoutePk: row.RoutePk, ID: row.ID} m[uid] = row @@ -161,6 +183,30 @@ func ListStopTimesForUpdate(ctx context.Context, querier db.Querier, tripUIDToPk return m, nil } +func MapVehicleIDToPkandTripPkToVehicleID( + ctx context.Context, + querier db.Querier, + systemPk int64, + vehicleIDs []string) (map[string]int64, map[int64]string, error) { + rows, err := querier.ListVehicleUniqueColumns(ctx, db.ListVehicleUniqueColumnsParams{ + SystemPk: systemPk, + VehicleIds: vehicleIDs, + }) + if err != nil { + return nil, nil, err + } + + vehicleIDToPk := map[string]int64{} + tripPkToVehicleID := map[int64]string{} + for _, row := range rows { + vehicleIDToPk[row.ID.String] = row.Pk + if row.TripPk.Valid { + tripPkToVehicleID[row.TripPk.Int64] = row.ID.String + } + } + return vehicleIDToPk, tripPkToVehicleID, nil +} + func Ping(ctx context.Context, logger *slog.Logger, pool *pgxpool.Pool, numRetries int, waitBetweenPings time.Duration) error { var err error ticker := time.NewTicker(waitBetweenPings) diff --git a/internal/gen/api/admin.pb.go b/internal/gen/api/admin.pb.go index fc3f754b..eb947745 100644 --- a/internal/gen/api/admin.pb.go +++ b/internal/gen/api/admin.pb.go @@ -1003,6 +1003,11 @@ type GtfsRealtimeOptions struct { // This should not be used for systems where a trip can call at the same // stop multiple times. ReassignStopSequences bool `protobuf:"varint,4,opt,name=reassign_stop_sequences,json=reassignStopSequences,proto3" json:"reassign_stop_sequences,omitempty"` + // If true, only process entities in a feed if the message contains + // the full entity. This is useful for cases where there are multiple + // feeds for the same system, and some feeds contain only partial + // information about entities. + OnlyProcessFullEntities bool `protobuf:"varint,5,opt,name=only_process_full_entities,json=onlyProcessFullEntities,proto3" json:"only_process_full_entities,omitempty"` } func (x *GtfsRealtimeOptions) Reset() { @@ -1065,6 +1070,13 @@ func (x *GtfsRealtimeOptions) GetReassignStopSequences() bool { return false } +func (x *GtfsRealtimeOptions) GetOnlyProcessFullEntities() bool { + if x != nil { + return x.OnlyProcessFullEntities + } + return false +} + // Description of the configuration for a collection of service maps. type ServiceMapConfig struct { state protoimpl.MessageState @@ -2131,7 +2143,7 @@ var file_api_admin_proto_rawDesc = []byte{ 0x65, 0x72, 0x69, 0x6f, 0x64, 0x5f, 0x6d, 0x73, 0x42, 0x12, 0x0a, 0x10, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x5f, 0x73, 0x42, 0x15, 0x0a, 0x13, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, - 0x5f, 0x6d, 0x73, 0x22, 0xe2, 0x08, 0x0a, 0x13, 0x47, 0x74, 0x66, 0x73, 0x52, 0x65, 0x61, 0x6c, + 0x5f, 0x6d, 0x73, 0x22, 0x9f, 0x09, 0x0a, 0x13, 0x47, 0x74, 0x66, 0x73, 0x52, 0x65, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3c, 0x0a, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x47, 0x74, 0x66, 0x73, 0x52, 0x65, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x65, 0x4f, 0x70, 0x74, @@ -2151,240 +2163,244 @@ var file_api_admin_proto_rawDesc = []byte{ 0x12, 0x36, 0x0a, 0x17, 0x72, 0x65, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x72, 0x65, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x53, 0x74, 0x6f, 0x70, 0x53, - 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x1a, 0xa8, 0x01, 0x0a, 0x10, 0x4e, 0x79, 0x63, - 0x74, 0x54, 0x72, 0x69, 0x70, 0x73, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, - 0x1d, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x6c, 0x65, 0x5f, 0x75, 0x6e, - 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x74, 0x72, 0x69, 0x70, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x53, 0x74, 0x61, 0x6c, - 0x65, 0x55, 0x6e, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x72, 0x69, 0x70, 0x73, - 0x12, 0x51, 0x0a, 0x26, 0x70, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x5f, 0x6d, 0x5f, 0x74, - 0x72, 0x61, 0x69, 0x6e, 0x5f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x5f, 0x69, - 0x6e, 0x5f, 0x62, 0x75, 0x73, 0x68, 0x77, 0x69, 0x63, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x21, 0x70, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x4d, 0x54, 0x72, 0x61, 0x69, 0x6e, - 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x49, 0x6e, 0x42, 0x75, 0x73, 0x68, 0x77, - 0x69, 0x63, 0x6b, 0x1a, 0xef, 0x03, 0x0a, 0x11, 0x4e, 0x79, 0x63, 0x74, 0x41, 0x6c, 0x65, 0x72, - 0x74, 0x73, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x99, 0x01, 0x0a, 0x24, 0x65, 0x6c, - 0x65, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x5f, 0x64, 0x65, - 0x64, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x48, 0x2e, 0x47, 0x74, 0x66, 0x73, 0x52, - 0x65, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4e, - 0x79, 0x63, 0x74, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x2e, 0x45, 0x6c, 0x65, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x44, + 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x1a, 0x6f, 0x6e, 0x6c, 0x79, + 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x66, 0x75, 0x6c, 0x6c, 0x5f, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x6f, 0x6e, + 0x6c, 0x79, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x46, 0x75, 0x6c, 0x6c, 0x45, 0x6e, 0x74, + 0x69, 0x74, 0x69, 0x65, 0x73, 0x1a, 0xa8, 0x01, 0x0a, 0x10, 0x4e, 0x79, 0x63, 0x74, 0x54, 0x72, + 0x69, 0x70, 0x73, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x1d, 0x66, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x6c, 0x65, 0x5f, 0x75, 0x6e, 0x61, 0x73, 0x73, + 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x74, 0x72, 0x69, 0x70, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x1a, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x53, 0x74, 0x61, 0x6c, 0x65, 0x55, 0x6e, + 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x72, 0x69, 0x70, 0x73, 0x12, 0x51, 0x0a, + 0x26, 0x70, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x5f, 0x6d, 0x5f, 0x74, 0x72, 0x61, 0x69, + 0x6e, 0x5f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x5f, 0x69, 0x6e, 0x5f, 0x62, + 0x75, 0x73, 0x68, 0x77, 0x69, 0x63, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x70, + 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x4d, 0x54, 0x72, 0x61, 0x69, 0x6e, 0x50, 0x6c, 0x61, + 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x49, 0x6e, 0x42, 0x75, 0x73, 0x68, 0x77, 0x69, 0x63, 0x6b, + 0x1a, 0xef, 0x03, 0x0a, 0x11, 0x4e, 0x79, 0x63, 0x74, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x99, 0x01, 0x0a, 0x24, 0x65, 0x6c, 0x65, 0x76, 0x61, + 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x5f, 0x64, 0x65, 0x64, 0x75, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x48, 0x2e, 0x47, 0x74, 0x66, 0x73, 0x52, 0x65, 0x61, 0x6c, + 0x74, 0x69, 0x6d, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4e, 0x79, 0x63, 0x74, + 0x41, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x45, 0x6c, + 0x65, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x44, 0x65, 0x64, 0x75, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, + 0x21, 0x65, 0x6c, 0x65, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x44, 0x65, 0x64, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x52, 0x21, 0x65, 0x6c, 0x65, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x65, 0x72, - 0x74, 0x73, 0x44, 0x65, 0x64, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x55, 0x0a, 0x28, 0x65, 0x6c, 0x65, 0x76, 0x61, 0x74, 0x6f, - 0x72, 0x5f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x5f, - 0x75, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, - 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x23, 0x65, 0x6c, 0x65, 0x76, 0x61, 0x74, 0x6f, - 0x72, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x55, 0x73, 0x69, - 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x48, 0x0a, 0x21, - 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f, - 0x6e, 0x6f, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x61, 0x6c, 0x65, 0x72, 0x74, - 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1d, 0x73, 0x6b, 0x69, 0x70, 0x54, 0x69, 0x6d, - 0x65, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x41, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x61, 0x64, 0x64, 0x5f, 0x6e, 0x79, - 0x63, 0x74, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0f, 0x61, 0x64, 0x64, 0x4e, 0x79, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x22, 0x71, 0x0a, 0x21, 0x45, 0x6c, 0x65, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x6c, - 0x65, 0x72, 0x74, 0x73, 0x44, 0x65, 0x64, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x14, 0x0a, 0x10, 0x4e, 0x4f, 0x5f, 0x44, 0x45, - 0x44, 0x55, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x00, 0x12, 0x1a, 0x0a, - 0x16, 0x44, 0x45, 0x44, 0x55, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x45, 0x5f, 0x49, 0x4e, 0x5f, - 0x53, 0x54, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x44, 0x45, 0x44, - 0x55, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x45, 0x5f, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x4d, 0x50, - 0x4c, 0x45, 0x58, 0x10, 0x02, 0x22, 0x52, 0x0a, 0x09, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x10, 0x0a, 0x0c, 0x4e, 0x4f, 0x5f, 0x45, 0x58, 0x54, 0x45, 0x4e, 0x53, 0x49, - 0x4f, 0x4e, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x4e, 0x59, 0x43, 0x54, 0x5f, 0x54, 0x52, 0x49, - 0x50, 0x53, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x4e, 0x59, 0x43, 0x54, 0x5f, 0x41, 0x4c, 0x45, - 0x52, 0x54, 0x53, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x4e, 0x59, 0x43, 0x54, 0x5f, 0x42, 0x55, - 0x53, 0x5f, 0x54, 0x52, 0x49, 0x50, 0x53, 0x10, 0x03, 0x42, 0x15, 0x0a, 0x13, 0x5f, 0x6e, 0x79, - 0x63, 0x74, 0x5f, 0x74, 0x72, 0x69, 0x70, 0x73, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x42, 0x16, 0x0a, 0x14, 0x5f, 0x6e, 0x79, 0x63, 0x74, 0x5f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x73, - 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xb8, 0x04, 0x0a, 0x10, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x0e, 0x0a, - 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x30, 0x0a, - 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, - 0x1c, 0x0a, 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x01, 0x52, 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x4b, 0x0a, - 0x0e, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4d, - 0x61, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x4f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x48, 0x00, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x88, 0x01, 0x01, 0x1a, 0xbf, 0x02, 0x0a, 0x0d, 0x53, - 0x74, 0x61, 0x74, 0x69, 0x63, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x33, 0x0a, 0x13, - 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x5f, 0x65, 0x61, 0x72, 0x6c, 0x69, 0x65, 0x72, 0x5f, 0x74, - 0x68, 0x61, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x48, 0x00, 0x52, 0x11, 0x73, 0x74, 0x61, - 0x72, 0x74, 0x73, 0x45, 0x61, 0x72, 0x6c, 0x69, 0x65, 0x72, 0x54, 0x68, 0x61, 0x6e, 0x88, 0x01, - 0x01, 0x12, 0x2f, 0x0a, 0x11, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x5f, 0x6c, 0x61, 0x74, 0x65, - 0x72, 0x5f, 0x74, 0x68, 0x61, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x48, 0x01, 0x52, 0x0f, - 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x4c, 0x61, 0x74, 0x65, 0x72, 0x54, 0x68, 0x61, 0x6e, 0x88, - 0x01, 0x01, 0x12, 0x2f, 0x0a, 0x11, 0x65, 0x6e, 0x64, 0x73, 0x5f, 0x65, 0x61, 0x72, 0x6c, 0x69, - 0x65, 0x72, 0x5f, 0x74, 0x68, 0x61, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x48, 0x02, 0x52, - 0x0f, 0x65, 0x6e, 0x64, 0x73, 0x45, 0x61, 0x72, 0x6c, 0x69, 0x65, 0x72, 0x54, 0x68, 0x61, 0x6e, - 0x88, 0x01, 0x01, 0x12, 0x2b, 0x0a, 0x0f, 0x65, 0x6e, 0x64, 0x73, 0x5f, 0x6c, 0x61, 0x74, 0x65, - 0x72, 0x5f, 0x74, 0x68, 0x61, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x48, 0x03, 0x52, 0x0d, - 0x65, 0x6e, 0x64, 0x73, 0x4c, 0x61, 0x74, 0x65, 0x72, 0x54, 0x68, 0x61, 0x6e, 0x88, 0x01, 0x01, - 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x79, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, - 0x64, 0x61, 0x79, 0x73, 0x42, 0x16, 0x0a, 0x14, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x5f, - 0x65, 0x61, 0x72, 0x6c, 0x69, 0x65, 0x72, 0x5f, 0x74, 0x68, 0x61, 0x6e, 0x42, 0x14, 0x0a, 0x12, - 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x5f, 0x6c, 0x61, 0x74, 0x65, 0x72, 0x5f, 0x74, 0x68, - 0x61, 0x6e, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x65, 0x6e, 0x64, 0x73, 0x5f, 0x65, 0x61, 0x72, 0x6c, - 0x69, 0x65, 0x72, 0x5f, 0x74, 0x68, 0x61, 0x6e, 0x42, 0x12, 0x0a, 0x10, 0x5f, 0x65, 0x6e, 0x64, - 0x73, 0x5f, 0x6c, 0x61, 0x74, 0x65, 0x72, 0x5f, 0x74, 0x68, 0x61, 0x6e, 0x22, 0x22, 0x0a, 0x06, - 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x54, 0x41, 0x54, 0x49, 0x43, - 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x45, 0x41, 0x4c, 0x54, 0x49, 0x4d, 0x45, 0x10, 0x01, - 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x6f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x22, 0x49, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, - 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x79, 0x73, 0x74, + 0x63, 0x79, 0x12, 0x55, 0x0a, 0x28, 0x65, 0x6c, 0x65, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, + 0x6c, 0x65, 0x72, 0x74, 0x73, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x75, 0x73, 0x69, + 0x6e, 0x67, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x23, 0x65, 0x6c, 0x65, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x6c, + 0x65, 0x72, 0x74, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x55, 0x73, 0x69, 0x6e, 0x67, 0x53, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x48, 0x0a, 0x21, 0x73, 0x6b, 0x69, + 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f, 0x6e, 0x6f, 0x5f, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x1d, 0x73, 0x6b, 0x69, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x6c, 0x65, + 0x72, 0x74, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x61, 0x64, 0x64, 0x5f, 0x6e, 0x79, 0x63, 0x74, 0x5f, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, + 0x61, 0x64, 0x64, 0x4e, 0x79, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, + 0x71, 0x0a, 0x21, 0x45, 0x6c, 0x65, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x65, 0x72, 0x74, + 0x73, 0x44, 0x65, 0x64, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x12, 0x14, 0x0a, 0x10, 0x4e, 0x4f, 0x5f, 0x44, 0x45, 0x44, 0x55, 0x50, + 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x44, 0x45, + 0x44, 0x55, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x45, 0x5f, 0x49, 0x4e, 0x5f, 0x53, 0x54, 0x41, + 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x44, 0x45, 0x44, 0x55, 0x50, 0x4c, + 0x49, 0x43, 0x41, 0x54, 0x45, 0x5f, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x58, + 0x10, 0x02, 0x22, 0x52, 0x0a, 0x09, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x10, 0x0a, 0x0c, 0x4e, 0x4f, 0x5f, 0x45, 0x58, 0x54, 0x45, 0x4e, 0x53, 0x49, 0x4f, 0x4e, 0x10, + 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x4e, 0x59, 0x43, 0x54, 0x5f, 0x54, 0x52, 0x49, 0x50, 0x53, 0x10, + 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x4e, 0x59, 0x43, 0x54, 0x5f, 0x41, 0x4c, 0x45, 0x52, 0x54, 0x53, + 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x4e, 0x59, 0x43, 0x54, 0x5f, 0x42, 0x55, 0x53, 0x5f, 0x54, + 0x52, 0x49, 0x50, 0x53, 0x10, 0x03, 0x42, 0x15, 0x0a, 0x13, 0x5f, 0x6e, 0x79, 0x63, 0x74, 0x5f, + 0x74, 0x72, 0x69, 0x70, 0x73, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x16, 0x0a, + 0x14, 0x5f, 0x6e, 0x79, 0x63, 0x74, 0x5f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x5f, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xb8, 0x04, 0x0a, 0x10, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x4d, 0x61, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x30, 0x0a, 0x06, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x53, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, + 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, + 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x4b, 0x0a, 0x0e, 0x73, 0x74, + 0x61, 0x74, 0x69, 0x63, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x48, 0x00, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x88, 0x01, 0x01, 0x1a, 0xbf, 0x02, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x74, + 0x69, 0x63, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x33, 0x0a, 0x13, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x73, 0x5f, 0x65, 0x61, 0x72, 0x6c, 0x69, 0x65, 0x72, 0x5f, 0x74, 0x68, 0x61, 0x6e, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x48, 0x00, 0x52, 0x11, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, + 0x45, 0x61, 0x72, 0x6c, 0x69, 0x65, 0x72, 0x54, 0x68, 0x61, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x2f, + 0x0a, 0x11, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x5f, 0x6c, 0x61, 0x74, 0x65, 0x72, 0x5f, 0x74, + 0x68, 0x61, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x48, 0x01, 0x52, 0x0f, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x73, 0x4c, 0x61, 0x74, 0x65, 0x72, 0x54, 0x68, 0x61, 0x6e, 0x88, 0x01, 0x01, 0x12, + 0x2f, 0x0a, 0x11, 0x65, 0x6e, 0x64, 0x73, 0x5f, 0x65, 0x61, 0x72, 0x6c, 0x69, 0x65, 0x72, 0x5f, + 0x74, 0x68, 0x61, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x48, 0x02, 0x52, 0x0f, 0x65, 0x6e, + 0x64, 0x73, 0x45, 0x61, 0x72, 0x6c, 0x69, 0x65, 0x72, 0x54, 0x68, 0x61, 0x6e, 0x88, 0x01, 0x01, + 0x12, 0x2b, 0x0a, 0x0f, 0x65, 0x6e, 0x64, 0x73, 0x5f, 0x6c, 0x61, 0x74, 0x65, 0x72, 0x5f, 0x74, + 0x68, 0x61, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x48, 0x03, 0x52, 0x0d, 0x65, 0x6e, 0x64, + 0x73, 0x4c, 0x61, 0x74, 0x65, 0x72, 0x54, 0x68, 0x61, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x12, 0x0a, + 0x04, 0x64, 0x61, 0x79, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x79, + 0x73, 0x42, 0x16, 0x0a, 0x14, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x5f, 0x65, 0x61, 0x72, + 0x6c, 0x69, 0x65, 0x72, 0x5f, 0x74, 0x68, 0x61, 0x6e, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x73, 0x5f, 0x6c, 0x61, 0x74, 0x65, 0x72, 0x5f, 0x74, 0x68, 0x61, 0x6e, 0x42, + 0x14, 0x0a, 0x12, 0x5f, 0x65, 0x6e, 0x64, 0x73, 0x5f, 0x65, 0x61, 0x72, 0x6c, 0x69, 0x65, 0x72, + 0x5f, 0x74, 0x68, 0x61, 0x6e, 0x42, 0x12, 0x0a, 0x10, 0x5f, 0x65, 0x6e, 0x64, 0x73, 0x5f, 0x6c, + 0x61, 0x74, 0x65, 0x72, 0x5f, 0x74, 0x68, 0x61, 0x6e, 0x22, 0x22, 0x0a, 0x06, 0x53, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x54, 0x41, 0x54, 0x49, 0x43, 0x10, 0x00, 0x12, + 0x0c, 0x0a, 0x08, 0x52, 0x45, 0x41, 0x4c, 0x54, 0x49, 0x4d, 0x45, 0x10, 0x01, 0x42, 0x11, 0x0a, + 0x0f, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x22, 0x49, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x64, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, + 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x65, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x65, 0x65, 0x64, 0x49, 0x64, 0x22, 0x82, 0x07, 0x0a, 0x0a, + 0x46, 0x65, 0x65, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0d, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x65, 0x64, 0x5f, 0x61, 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x41, 0x74, 0x4d, 0x73, 0x12, 0x29, 0x0a, 0x0e, 0x66, + 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x0c, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x41, + 0x74, 0x4d, 0x73, 0x88, 0x01, 0x01, 0x12, 0x2d, 0x0a, 0x10, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, + 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x6d, 0x73, 0x18, 0x14, 0x20, 0x01, 0x28, 0x03, + 0x48, 0x01, 0x52, 0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x4c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, + 0x4d, 0x73, 0x88, 0x01, 0x01, 0x12, 0x33, 0x0a, 0x13, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, + 0x64, 0x5f, 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x6d, 0x73, 0x18, 0x15, 0x20, 0x01, + 0x28, 0x03, 0x48, 0x02, 0x52, 0x11, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x61, + 0x74, 0x65, 0x6e, 0x63, 0x79, 0x4d, 0x73, 0x88, 0x01, 0x01, 0x12, 0x2d, 0x0a, 0x10, 0x70, 0x61, + 0x72, 0x73, 0x65, 0x5f, 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x6d, 0x73, 0x18, 0x16, + 0x20, 0x01, 0x28, 0x03, 0x48, 0x03, 0x52, 0x0e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x4c, 0x61, 0x74, + 0x65, 0x6e, 0x63, 0x79, 0x4d, 0x73, 0x88, 0x01, 0x01, 0x12, 0x2f, 0x0a, 0x11, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x5f, 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x6d, 0x73, 0x18, 0x17, + 0x20, 0x01, 0x28, 0x03, 0x48, 0x04, 0x52, 0x0f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4c, 0x61, + 0x74, 0x65, 0x6e, 0x63, 0x79, 0x4d, 0x73, 0x88, 0x01, 0x01, 0x12, 0x2a, 0x0a, 0x06, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x46, 0x65, 0x65, + 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2a, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x48, 0x05, + 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x88, + 0x01, 0x01, 0x12, 0x26, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x68, 0x61, + 0x73, 0x68, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x48, 0x06, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x48, 0x61, 0x73, 0x68, 0x88, 0x01, 0x01, 0x12, 0x28, 0x0a, 0x0d, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x09, 0x48, 0x07, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x88, 0x01, 0x01, 0x22, 0xf8, 0x01, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, + 0x52, 0x55, 0x4e, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x50, 0x44, + 0x41, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x4b, 0x49, 0x50, 0x50, 0x45, + 0x44, 0x10, 0x03, 0x12, 0x19, 0x0a, 0x15, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x44, 0x4f, + 0x57, 0x4e, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x04, 0x12, 0x15, + 0x0a, 0x11, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x45, 0x4d, 0x50, 0x54, 0x59, 0x5f, 0x46, + 0x45, 0x45, 0x44, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, + 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x46, 0x45, 0x45, 0x44, 0x5f, 0x43, 0x4f, 0x4e, + 0x46, 0x49, 0x47, 0x10, 0x06, 0x12, 0x16, 0x0a, 0x12, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, + 0x50, 0x41, 0x52, 0x53, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x08, 0x12, 0x17, 0x0a, + 0x13, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x10, 0x09, 0x12, 0x19, 0x0a, 0x15, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, + 0x5f, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, + 0x0a, 0x12, 0x1c, 0x0a, 0x18, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, + 0x4f, 0x57, 0x4e, 0x5f, 0x46, 0x45, 0x45, 0x44, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x0b, 0x42, + 0x11, 0x0a, 0x0f, 0x5f, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x5f, + 0x6d, 0x73, 0x42, 0x13, 0x0a, 0x11, 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x6c, 0x61, 0x74, + 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x6d, 0x73, 0x42, 0x16, 0x0a, 0x14, 0x5f, 0x64, 0x6f, 0x77, 0x6e, + 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x6d, 0x73, 0x42, + 0x13, 0x0a, 0x11, 0x5f, 0x70, 0x61, 0x72, 0x73, 0x65, 0x5f, 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, + 0x79, 0x5f, 0x6d, 0x73, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, + 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x6d, 0x73, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x42, 0x0f, 0x0a, + 0x0d, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x42, 0x10, + 0x0a, 0x0e, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x22, 0x3f, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x64, 0x52, 0x65, + 0x70, 0x6c, 0x79, 0x12, 0x2c, 0x0a, 0x0b, 0x66, 0x65, 0x65, 0x64, 0x5f, 0x75, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x46, 0x65, 0x65, 0x64, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x0a, 0x66, 0x65, 0x65, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x22, 0x1b, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, + 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xb7, + 0x02, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x33, 0x0a, 0x05, 0x66, 0x65, + 0x65, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x47, 0x65, 0x74, 0x53, + 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, + 0x70, 0x6c, 0x79, 0x2e, 0x46, 0x65, 0x65, 0x64, 0x52, 0x05, 0x66, 0x65, 0x65, 0x64, 0x73, 0x1a, + 0xe6, 0x01, 0x0a, 0x04, 0x46, 0x65, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x79, 0x73, - 0x74, 0x65, 0x6d, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x65, 0x65, 0x64, 0x5f, 0x69, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x65, 0x65, 0x64, 0x49, 0x64, 0x22, 0x82, - 0x07, 0x0a, 0x0a, 0x46, 0x65, 0x65, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x1b, 0x0a, - 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0d, 0x73, 0x74, - 0x61, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x0b, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x41, 0x74, 0x4d, 0x73, 0x12, 0x29, - 0x0a, 0x0e, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x5f, 0x6d, 0x73, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x0c, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, - 0x65, 0x64, 0x41, 0x74, 0x4d, 0x73, 0x88, 0x01, 0x01, 0x12, 0x2d, 0x0a, 0x10, 0x74, 0x6f, 0x74, - 0x61, 0x6c, 0x5f, 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x6d, 0x73, 0x18, 0x14, 0x20, - 0x01, 0x28, 0x03, 0x48, 0x01, 0x52, 0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x4c, 0x61, 0x74, 0x65, - 0x6e, 0x63, 0x79, 0x4d, 0x73, 0x88, 0x01, 0x01, 0x12, 0x33, 0x0a, 0x13, 0x64, 0x6f, 0x77, 0x6e, - 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x6d, 0x73, 0x18, - 0x15, 0x20, 0x01, 0x28, 0x03, 0x48, 0x02, 0x52, 0x11, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, - 0x64, 0x4c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x4d, 0x73, 0x88, 0x01, 0x01, 0x12, 0x2d, 0x0a, - 0x10, 0x70, 0x61, 0x72, 0x73, 0x65, 0x5f, 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x6d, - 0x73, 0x18, 0x16, 0x20, 0x01, 0x28, 0x03, 0x48, 0x03, 0x52, 0x0e, 0x70, 0x61, 0x72, 0x73, 0x65, - 0x4c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x4d, 0x73, 0x88, 0x01, 0x01, 0x12, 0x2f, 0x0a, 0x11, - 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x6d, - 0x73, 0x18, 0x17, 0x20, 0x01, 0x28, 0x03, 0x48, 0x04, 0x52, 0x0f, 0x75, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x4c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x4d, 0x73, 0x88, 0x01, 0x01, 0x12, 0x2a, 0x0a, - 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, - 0x46, 0x65, 0x65, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2a, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, - 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, - 0x05, 0x48, 0x05, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x4c, 0x65, 0x6e, 0x67, - 0x74, 0x68, 0x88, 0x01, 0x01, 0x12, 0x26, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, - 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x48, 0x06, 0x52, 0x0b, 0x63, - 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x48, 0x61, 0x73, 0x68, 0x88, 0x01, 0x01, 0x12, 0x28, 0x0a, - 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x0a, - 0x20, 0x01, 0x28, 0x09, 0x48, 0x07, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x88, 0x01, 0x01, 0x22, 0xf8, 0x01, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, - 0x0b, 0x0a, 0x07, 0x52, 0x55, 0x4e, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, - 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x4b, 0x49, - 0x50, 0x50, 0x45, 0x44, 0x10, 0x03, 0x12, 0x19, 0x0a, 0x15, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, - 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, - 0x04, 0x12, 0x15, 0x0a, 0x11, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x45, 0x4d, 0x50, 0x54, - 0x59, 0x5f, 0x46, 0x45, 0x45, 0x44, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x46, 0x41, 0x49, 0x4c, - 0x45, 0x44, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x46, 0x45, 0x45, 0x44, 0x5f, - 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x10, 0x06, 0x12, 0x16, 0x0a, 0x12, 0x46, 0x41, 0x49, 0x4c, - 0x45, 0x44, 0x5f, 0x50, 0x41, 0x52, 0x53, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x08, - 0x12, 0x17, 0x0a, 0x13, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, - 0x45, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x09, 0x12, 0x19, 0x0a, 0x15, 0x46, 0x41, 0x49, - 0x4c, 0x45, 0x44, 0x5f, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x10, 0x0a, 0x12, 0x1c, 0x0a, 0x18, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x55, - 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x46, 0x45, 0x45, 0x44, 0x5f, 0x54, 0x59, 0x50, 0x45, - 0x10, 0x0b, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x5f, - 0x61, 0x74, 0x5f, 0x6d, 0x73, 0x42, 0x13, 0x0a, 0x11, 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, - 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x6d, 0x73, 0x42, 0x16, 0x0a, 0x14, 0x5f, 0x64, - 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x5f, - 0x6d, 0x73, 0x42, 0x13, 0x0a, 0x11, 0x5f, 0x70, 0x61, 0x72, 0x73, 0x65, 0x5f, 0x6c, 0x61, 0x74, - 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x6d, 0x73, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x75, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x5f, 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x6d, 0x73, 0x42, 0x11, 0x0a, - 0x0f, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, - 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x68, 0x61, 0x73, - 0x68, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x22, 0x3f, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, - 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x2c, 0x0a, 0x0b, 0x66, 0x65, 0x65, 0x64, 0x5f, 0x75, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x46, 0x65, - 0x65, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x0a, 0x66, 0x65, 0x65, 0x64, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x22, 0x1b, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, - 0x75, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x22, 0xb7, 0x02, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, - 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x33, 0x0a, - 0x05, 0x66, 0x65, 0x65, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x47, - 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x2e, 0x46, 0x65, 0x65, 0x64, 0x52, 0x05, 0x66, 0x65, 0x65, - 0x64, 0x73, 0x1a, 0xe6, 0x01, 0x0a, 0x04, 0x46, 0x65, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x73, - 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x0b, 0x66, 0x65, 0x65, 0x64, - 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, - 0x46, 0x65, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0a, 0x66, 0x65, 0x65, 0x64, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x34, 0x0a, 0x16, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, - 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x14, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x75, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x30, 0x0a, 0x14, - 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x5f, 0x75, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, 0x6c, 0x61, 0x73, 0x74, - 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x2b, - 0x0a, 0x11, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x6e, - 0x69, 0x6e, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x63, 0x75, 0x72, 0x72, 0x65, - 0x6e, 0x74, 0x6c, 0x79, 0x52, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x22, 0x17, 0x0a, 0x15, 0x52, - 0x65, 0x73, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x22, 0x15, 0x0a, 0x13, 0x52, 0x65, 0x73, 0x65, 0x74, 0x53, 0x63, 0x68, - 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x14, 0x0a, 0x12, 0x47, - 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x22, 0x2f, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, - 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x6f, 0x67, 0x5f, 0x6c, 0x65, 0x76, + 0x74, 0x65, 0x6d, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x0b, 0x66, 0x65, 0x65, 0x64, 0x5f, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x46, 0x65, 0x65, + 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0a, 0x66, 0x65, 0x65, 0x64, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x12, 0x34, 0x0a, 0x16, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x75, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x14, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x66, 0x75, 0x6c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x6c, 0x61, 0x73, + 0x74, 0x5f, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, 0x6c, 0x61, 0x73, 0x74, 0x46, 0x69, 0x6e, + 0x69, 0x73, 0x68, 0x65, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x63, + 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x6c, + 0x79, 0x52, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x22, 0x17, 0x0a, 0x15, 0x52, 0x65, 0x73, 0x65, + 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x22, 0x15, 0x0a, 0x13, 0x52, 0x65, 0x73, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, + 0x6c, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x14, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x4c, + 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x2f, + 0x0a, 0x10, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x65, 0x70, + 0x6c, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x6f, 0x67, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x22, + 0x31, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x6f, 0x67, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x67, 0x4c, 0x65, 0x76, - 0x65, 0x6c, 0x22, 0x31, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, - 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x6f, 0x67, 0x5f, - 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x67, - 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0x12, 0x0a, 0x10, 0x53, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x4c, - 0x65, 0x76, 0x65, 0x6c, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x32, 0xdf, 0x05, 0x0a, 0x05, 0x41, 0x64, - 0x6d, 0x69, 0x6e, 0x12, 0x5e, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x17, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x79, 0x73, 0x74, - 0x65, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x0d, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x23, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, - 0x2f, 0x7b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x12, 0x74, 0x0a, 0x15, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x4f, 0x72, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x1d, 0x2e, 0x49, - 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x4f, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x79, - 0x73, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x49, 0x6e, - 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x4f, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x79, 0x73, - 0x74, 0x65, 0x6d, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, - 0x3a, 0x01, 0x2a, 0x1a, 0x14, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2f, 0x7b, 0x73, - 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x56, 0x0a, 0x0c, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x14, 0x2e, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x12, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x65, - 0x70, 0x6c, 0x79, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x2a, 0x14, 0x2f, 0x73, 0x79, - 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2f, 0x7b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, - 0x7d, 0x12, 0x60, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x64, 0x12, - 0x12, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x64, - 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x2c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x22, 0x24, 0x2f, - 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2f, 0x7b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, - 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x65, 0x65, 0x64, 0x73, 0x2f, 0x7b, 0x66, 0x65, 0x65, 0x64, 0x5f, - 0x69, 0x64, 0x7d, 0x12, 0x5e, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, - 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1a, 0x2e, 0x47, 0x65, 0x74, 0x53, - 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, - 0x75, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, - 0x12, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0c, 0x12, 0x0a, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, - 0x6c, 0x65, 0x72, 0x12, 0x52, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, - 0x64, 0x75, 0x6c, 0x65, 0x72, 0x12, 0x16, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x53, 0x63, 0x68, - 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, - 0x52, 0x65, 0x73, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x52, 0x65, - 0x70, 0x6c, 0x79, 0x22, 0x12, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0c, 0x22, 0x0a, 0x2f, 0x73, 0x63, - 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x12, 0x48, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4c, 0x6f, - 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x13, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x4c, - 0x65, 0x76, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x47, 0x65, - 0x74, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x11, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0b, 0x12, 0x09, 0x2f, 0x6c, 0x6f, 0x67, 0x6c, 0x65, 0x76, 0x65, - 0x6c, 0x12, 0x48, 0x0a, 0x0b, 0x53, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, - 0x12, 0x13, 0x2e, 0x53, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x53, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x4c, 0x65, - 0x76, 0x65, 0x6c, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x11, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0b, - 0x1a, 0x09, 0x2f, 0x6c, 0x6f, 0x67, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x42, 0x28, 0x5a, 0x26, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6a, 0x61, 0x6d, 0x65, 0x73, 0x70, - 0x66, 0x65, 0x6e, 0x6e, 0x65, 0x6c, 0x6c, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x65, - 0x72, 0x2f, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x6c, 0x22, 0x12, 0x0a, 0x10, 0x53, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, + 0x6c, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x32, 0xdf, 0x05, 0x0a, 0x05, 0x41, 0x64, 0x6d, 0x69, 0x6e, + 0x12, 0x5e, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x12, 0x17, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0d, 0x2e, 0x53, + 0x79, 0x73, 0x74, 0x65, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x23, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2f, 0x7b, 0x73, + 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x12, 0x74, 0x0a, 0x15, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x4f, 0x72, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x1d, 0x2e, 0x49, 0x6e, 0x73, 0x74, + 0x61, 0x6c, 0x6c, 0x4f, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, + 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, + 0x6c, 0x6c, 0x4f, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, + 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x3a, 0x01, 0x2a, + 0x1a, 0x14, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2f, 0x7b, 0x73, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x56, 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x14, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, + 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x70, 0x6c, 0x79, + 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x2a, 0x14, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, + 0x6d, 0x73, 0x2f, 0x7b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x60, + 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x64, 0x12, 0x12, 0x2e, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x10, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x64, 0x52, 0x65, 0x70, + 0x6c, 0x79, 0x22, 0x2c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x22, 0x24, 0x2f, 0x73, 0x79, 0x73, + 0x74, 0x65, 0x6d, 0x73, 0x2f, 0x7b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x7d, + 0x2f, 0x66, 0x65, 0x65, 0x64, 0x73, 0x2f, 0x7b, 0x66, 0x65, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x7d, + 0x12, 0x5e, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1a, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, + 0x64, 0x75, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, + 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x12, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x0c, 0x12, 0x0a, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, + 0x12, 0x52, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, + 0x65, 0x72, 0x12, 0x16, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, + 0x6c, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x52, 0x65, 0x73, + 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6c, 0x79, + 0x22, 0x12, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0c, 0x22, 0x0a, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x64, + 0x75, 0x6c, 0x65, 0x72, 0x12, 0x48, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x4c, 0x65, + 0x76, 0x65, 0x6c, 0x12, 0x13, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, + 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x6f, + 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x11, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x0b, 0x12, 0x09, 0x2f, 0x6c, 0x6f, 0x67, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x48, + 0x0a, 0x0b, 0x53, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x13, 0x2e, + 0x53, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x53, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, + 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x11, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0b, 0x1a, 0x09, 0x2f, + 0x6c, 0x6f, 0x67, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x42, 0x28, 0x5a, 0x26, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6a, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x66, 0x65, 0x6e, + 0x6e, 0x65, 0x6c, 0x6c, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x65, 0x72, 0x2f, 0x61, + 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/internal/gen/api/public.pb.go b/internal/gen/api/public.pb.go index 01e32a55..a342e973 100644 --- a/internal/gen/api/public.pb.go +++ b/internal/gen/api/public.pb.go @@ -129,6 +129,54 @@ func (ListStopsRequest_SearchMode) EnumDescriptor() ([]byte, []int) { return file_api_public_proto_rawDescGZIP(), []int{8, 0} } +type ListVehiclesRequest_SearchMode int32 + +const ( + // Return a paginated list of vehicles sorted by vehicle ID. + ListVehiclesRequest_ID ListVehiclesRequest_SearchMode = 0 + // Return all vehicles within max_distance of (latitude, longitude), sorted by the distance. + ListVehiclesRequest_DISTANCE ListVehiclesRequest_SearchMode = 1 +) + +// Enum value maps for ListVehiclesRequest_SearchMode. +var ( + ListVehiclesRequest_SearchMode_name = map[int32]string{ + 0: "ID", + 1: "DISTANCE", + } + ListVehiclesRequest_SearchMode_value = map[string]int32{ + "ID": 0, + "DISTANCE": 1, + } +) + +func (x ListVehiclesRequest_SearchMode) Enum() *ListVehiclesRequest_SearchMode { + p := new(ListVehiclesRequest_SearchMode) + *p = x + return p +} + +func (x ListVehiclesRequest_SearchMode) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ListVehiclesRequest_SearchMode) Descriptor() protoreflect.EnumDescriptor { + return file_api_public_proto_enumTypes[1].Descriptor() +} + +func (ListVehiclesRequest_SearchMode) Type() protoreflect.EnumType { + return &file_api_public_proto_enumTypes[1] +} + +func (x ListVehiclesRequest_SearchMode) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ListVehiclesRequest_SearchMode.Descriptor instead. +func (ListVehiclesRequest_SearchMode) EnumDescriptor() ([]byte, []int) { + return file_api_public_proto_rawDescGZIP(), []int{25, 0} +} + // Enum describing the possible statuses of a system. type System_Status int32 @@ -182,11 +230,11 @@ func (x System_Status) String() string { } func (System_Status) Descriptor() protoreflect.EnumDescriptor { - return file_api_public_proto_enumTypes[1].Descriptor() + return file_api_public_proto_enumTypes[2].Descriptor() } func (System_Status) Type() protoreflect.EnumType { - return &file_api_public_proto_enumTypes[1] + return &file_api_public_proto_enumTypes[2] } func (x System_Status) Number() protoreflect.EnumNumber { @@ -195,7 +243,7 @@ func (x System_Status) Number() protoreflect.EnumNumber { // Deprecated: Use System_Status.Descriptor instead. func (System_Status) EnumDescriptor() ([]byte, []int) { - return file_api_public_proto_rawDescGZIP(), []int{25, 0} + return file_api_public_proto_rawDescGZIP(), []int{28, 0} } // Enum describing the possible stop types @@ -238,11 +286,11 @@ func (x Stop_Type) String() string { } func (Stop_Type) Descriptor() protoreflect.EnumDescriptor { - return file_api_public_proto_enumTypes[2].Descriptor() + return file_api_public_proto_enumTypes[3].Descriptor() } func (Stop_Type) Type() protoreflect.EnumType { - return &file_api_public_proto_enumTypes[2] + return &file_api_public_proto_enumTypes[3] } func (x Stop_Type) Number() protoreflect.EnumNumber { @@ -251,7 +299,178 @@ func (x Stop_Type) Number() protoreflect.EnumNumber { // Deprecated: Use Stop_Type.Descriptor instead. func (Stop_Type) EnumDescriptor() ([]byte, []int) { - return file_api_public_proto_rawDescGZIP(), []int{28, 0} + return file_api_public_proto_rawDescGZIP(), []int{31, 0} +} + +// Corresponds to [VehicleStopStatus](https://developers.google.com/ +// transit/gtfs-realtime/reference#enum-vehiclestopstatus). +type Vehicle_CurrentStatus int32 + +const ( + Vehicle_INCOMING_AT Vehicle_CurrentStatus = 0 + Vehicle_STOPPED_AT Vehicle_CurrentStatus = 1 + Vehicle_IN_TRANSIT_TO Vehicle_CurrentStatus = 2 +) + +// Enum value maps for Vehicle_CurrentStatus. +var ( + Vehicle_CurrentStatus_name = map[int32]string{ + 0: "INCOMING_AT", + 1: "STOPPED_AT", + 2: "IN_TRANSIT_TO", + } + Vehicle_CurrentStatus_value = map[string]int32{ + "INCOMING_AT": 0, + "STOPPED_AT": 1, + "IN_TRANSIT_TO": 2, + } +) + +func (x Vehicle_CurrentStatus) Enum() *Vehicle_CurrentStatus { + p := new(Vehicle_CurrentStatus) + *p = x + return p +} + +func (x Vehicle_CurrentStatus) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Vehicle_CurrentStatus) Descriptor() protoreflect.EnumDescriptor { + return file_api_public_proto_enumTypes[4].Descriptor() +} + +func (Vehicle_CurrentStatus) Type() protoreflect.EnumType { + return &file_api_public_proto_enumTypes[4] +} + +func (x Vehicle_CurrentStatus) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Vehicle_CurrentStatus.Descriptor instead. +func (Vehicle_CurrentStatus) EnumDescriptor() ([]byte, []int) { + return file_api_public_proto_rawDescGZIP(), []int{34, 0} +} + +// Corresponds to [CongestionLevel](https://developers.google.com/ +// transit/gtfs-realtime/reference#enum-congestionlevel). +type Vehicle_CongestionLevel int32 + +const ( + Vehicle_UNKNOWN_CONGESTION_LEVEL Vehicle_CongestionLevel = 0 + Vehicle_RUNNING_SMOOTHLY Vehicle_CongestionLevel = 1 + Vehicle_STOP_AND_GO Vehicle_CongestionLevel = 2 + Vehicle_CONGESTION Vehicle_CongestionLevel = 3 + Vehicle_SEVERE_CONGESTION Vehicle_CongestionLevel = 4 +) + +// Enum value maps for Vehicle_CongestionLevel. +var ( + Vehicle_CongestionLevel_name = map[int32]string{ + 0: "UNKNOWN_CONGESTION_LEVEL", + 1: "RUNNING_SMOOTHLY", + 2: "STOP_AND_GO", + 3: "CONGESTION", + 4: "SEVERE_CONGESTION", + } + Vehicle_CongestionLevel_value = map[string]int32{ + "UNKNOWN_CONGESTION_LEVEL": 0, + "RUNNING_SMOOTHLY": 1, + "STOP_AND_GO": 2, + "CONGESTION": 3, + "SEVERE_CONGESTION": 4, + } +) + +func (x Vehicle_CongestionLevel) Enum() *Vehicle_CongestionLevel { + p := new(Vehicle_CongestionLevel) + *p = x + return p +} + +func (x Vehicle_CongestionLevel) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Vehicle_CongestionLevel) Descriptor() protoreflect.EnumDescriptor { + return file_api_public_proto_enumTypes[5].Descriptor() +} + +func (Vehicle_CongestionLevel) Type() protoreflect.EnumType { + return &file_api_public_proto_enumTypes[5] +} + +func (x Vehicle_CongestionLevel) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Vehicle_CongestionLevel.Descriptor instead. +func (Vehicle_CongestionLevel) EnumDescriptor() ([]byte, []int) { + return file_api_public_proto_rawDescGZIP(), []int{34, 1} +} + +// Corresponds to [OccupancyStatus](https://developers.google.com/ +// transit/gtfs-realtime/reference#enum-occupancystatus). +type Vehicle_OccupancyStatus int32 + +const ( + Vehicle_EMPTY Vehicle_OccupancyStatus = 0 + Vehicle_MANY_SEATS_AVAILABLE Vehicle_OccupancyStatus = 1 + Vehicle_FEW_SEATS_AVAILABLE Vehicle_OccupancyStatus = 2 + Vehicle_STANDING_ROOM_ONLY Vehicle_OccupancyStatus = 3 + Vehicle_CRUSHED_STANDING_ROOM_ONLY Vehicle_OccupancyStatus = 4 + Vehicle_FULL Vehicle_OccupancyStatus = 5 + Vehicle_NOT_ACCEPTING_PASSENGERS Vehicle_OccupancyStatus = 6 +) + +// Enum value maps for Vehicle_OccupancyStatus. +var ( + Vehicle_OccupancyStatus_name = map[int32]string{ + 0: "EMPTY", + 1: "MANY_SEATS_AVAILABLE", + 2: "FEW_SEATS_AVAILABLE", + 3: "STANDING_ROOM_ONLY", + 4: "CRUSHED_STANDING_ROOM_ONLY", + 5: "FULL", + 6: "NOT_ACCEPTING_PASSENGERS", + } + Vehicle_OccupancyStatus_value = map[string]int32{ + "EMPTY": 0, + "MANY_SEATS_AVAILABLE": 1, + "FEW_SEATS_AVAILABLE": 2, + "STANDING_ROOM_ONLY": 3, + "CRUSHED_STANDING_ROOM_ONLY": 4, + "FULL": 5, + "NOT_ACCEPTING_PASSENGERS": 6, + } +) + +func (x Vehicle_OccupancyStatus) Enum() *Vehicle_OccupancyStatus { + p := new(Vehicle_OccupancyStatus) + *p = x + return p +} + +func (x Vehicle_OccupancyStatus) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Vehicle_OccupancyStatus) Descriptor() protoreflect.EnumDescriptor { + return file_api_public_proto_enumTypes[6].Descriptor() +} + +func (Vehicle_OccupancyStatus) Type() protoreflect.EnumType { + return &file_api_public_proto_enumTypes[6] +} + +func (x Vehicle_OccupancyStatus) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Vehicle_OccupancyStatus.Descriptor instead. +func (Vehicle_OccupancyStatus) EnumDescriptor() ([]byte, []int) { + return file_api_public_proto_rawDescGZIP(), []int{34, 2} } // Enum describing possible policies for continuous pickup or drop-off. @@ -295,11 +514,11 @@ func (x Route_ContinuousPolicy) String() string { } func (Route_ContinuousPolicy) Descriptor() protoreflect.EnumDescriptor { - return file_api_public_proto_enumTypes[3].Descriptor() + return file_api_public_proto_enumTypes[7].Descriptor() } func (Route_ContinuousPolicy) Type() protoreflect.EnumType { - return &file_api_public_proto_enumTypes[3] + return &file_api_public_proto_enumTypes[7] } func (x Route_ContinuousPolicy) Number() protoreflect.EnumNumber { @@ -308,7 +527,7 @@ func (x Route_ContinuousPolicy) Number() protoreflect.EnumNumber { // Deprecated: Use Route_ContinuousPolicy.Descriptor instead. func (Route_ContinuousPolicy) EnumDescriptor() ([]byte, []int) { - return file_api_public_proto_rawDescGZIP(), []int{32, 0} + return file_api_public_proto_rawDescGZIP(), []int{35, 0} } // Enum describing possible route types. @@ -370,11 +589,11 @@ func (x Route_Type) String() string { } func (Route_Type) Descriptor() protoreflect.EnumDescriptor { - return file_api_public_proto_enumTypes[4].Descriptor() + return file_api_public_proto_enumTypes[8].Descriptor() } func (Route_Type) Type() protoreflect.EnumType { - return &file_api_public_proto_enumTypes[4] + return &file_api_public_proto_enumTypes[8] } func (x Route_Type) Number() protoreflect.EnumNumber { @@ -383,7 +602,7 @@ func (x Route_Type) Number() protoreflect.EnumNumber { // Deprecated: Use Route_Type.Descriptor instead. func (Route_Type) EnumDescriptor() ([]byte, []int) { - return file_api_public_proto_rawDescGZIP(), []int{32, 1} + return file_api_public_proto_rawDescGZIP(), []int{35, 1} } // Cause is the same as the [cause enum in the GTFS realtime @@ -449,11 +668,11 @@ func (x Alert_Cause) String() string { } func (Alert_Cause) Descriptor() protoreflect.EnumDescriptor { - return file_api_public_proto_enumTypes[5].Descriptor() + return file_api_public_proto_enumTypes[9].Descriptor() } func (Alert_Cause) Type() protoreflect.EnumType { - return &file_api_public_proto_enumTypes[5] + return &file_api_public_proto_enumTypes[9] } func (x Alert_Cause) Number() protoreflect.EnumNumber { @@ -462,7 +681,7 @@ func (x Alert_Cause) Number() protoreflect.EnumNumber { // Deprecated: Use Alert_Cause.Descriptor instead. func (Alert_Cause) EnumDescriptor() ([]byte, []int) { - return file_api_public_proto_rawDescGZIP(), []int{35, 0} + return file_api_public_proto_rawDescGZIP(), []int{38, 0} } // Effect is the same as the [effect enum in the GTFS realtime @@ -525,11 +744,11 @@ func (x Alert_Effect) String() string { } func (Alert_Effect) Descriptor() protoreflect.EnumDescriptor { - return file_api_public_proto_enumTypes[6].Descriptor() + return file_api_public_proto_enumTypes[10].Descriptor() } func (Alert_Effect) Type() protoreflect.EnumType { - return &file_api_public_proto_enumTypes[6] + return &file_api_public_proto_enumTypes[10] } func (x Alert_Effect) Number() protoreflect.EnumNumber { @@ -538,7 +757,7 @@ func (x Alert_Effect) Number() protoreflect.EnumNumber { // Deprecated: Use Alert_Effect.Descriptor instead. func (Alert_Effect) EnumDescriptor() ([]byte, []int) { - return file_api_public_proto_rawDescGZIP(), []int{35, 1} + return file_api_public_proto_rawDescGZIP(), []int{38, 1} } type Transfer_Type int32 @@ -577,11 +796,11 @@ func (x Transfer_Type) String() string { } func (Transfer_Type) Descriptor() protoreflect.EnumDescriptor { - return file_api_public_proto_enumTypes[7].Descriptor() + return file_api_public_proto_enumTypes[11].Descriptor() } func (Transfer_Type) Type() protoreflect.EnumType { - return &file_api_public_proto_enumTypes[7] + return &file_api_public_proto_enumTypes[11] } func (x Transfer_Type) Number() protoreflect.EnumNumber { @@ -590,7 +809,7 @@ func (x Transfer_Type) Number() protoreflect.EnumNumber { // Deprecated: Use Transfer_Type.Descriptor instead. func (Transfer_Type) EnumDescriptor() ([]byte, []int) { - return file_api_public_proto_rawDescGZIP(), []int{36, 0} + return file_api_public_proto_rawDescGZIP(), []int{39, 0} } // Request payload for the entrypoint endpoint. @@ -2160,6 +2379,251 @@ func (x *ListTransfersReply) GetTransfers() []*Transfer { return nil } +type ListVehiclesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // ID of the system for which to list vehicles. + SystemId string `protobuf:"bytes,1,opt,name=system_id,json=systemId,proto3" json:"system_id,omitempty"` + // The type of search to perform when listing vehicles. + SearchMode *ListVehiclesRequest_SearchMode `protobuf:"varint,2,opt,name=search_mode,json=searchMode,proto3,enum=ListVehiclesRequest_SearchMode,oneof" json:"search_mode,omitempty"` + // If true, only return vehicles whose IDs are specified in the repeated `id` field. + // Only supported when the search mode is ID. + OnlyReturnSpecifiedIds bool `protobuf:"varint,3,opt,name=only_return_specified_ids,json=onlyReturnSpecifiedIds,proto3" json:"only_return_specified_ids,omitempty"` + // IDs to return if `only_return_specified_ids` is set to true. It is an error to + // populate this field if `only_return_specified_ids` is false. + // Only supported when the search mode is ID. + Id []string `protobuf:"bytes,4,rep,name=id,proto3" json:"id,omitempty"` + // ID of the first vehicle to return. If not set, the vehicle with the smallest ID will be first. + // Only supported when the search mode is ID. + FirstId *string `protobuf:"bytes,5,opt,name=first_id,json=firstId,proto3,oneof" json:"first_id,omitempty"` + // Maximum number of vehicles to return. + // This is supported in all search modes. + // For performance reasons, if it is larger than 100 it is rounded down to 100. + Limit *int32 `protobuf:"varint,6,opt,name=limit,proto3,oneof" json:"limit,omitempty"` + // The maximum distance in kilometers that a vehicle must be from + // latitude, longitude to be listed when using DISTANCE search mode. + MaxDistance *float64 `protobuf:"fixed64,7,opt,name=max_distance,json=maxDistance,proto3,oneof" json:"max_distance,omitempty"` + // The latitude relative to the returned vehicles when using DISTANCE search mode. + Latitude *float64 `protobuf:"fixed64,8,opt,name=latitude,proto3,oneof" json:"latitude,omitempty"` + // The longitude relative to the returned vehicles when using DISTANCE search mode. + Longitude *float64 `protobuf:"fixed64,9,opt,name=longitude,proto3,oneof" json:"longitude,omitempty"` +} + +func (x *ListVehiclesRequest) Reset() { + *x = ListVehiclesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_public_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListVehiclesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListVehiclesRequest) ProtoMessage() {} + +func (x *ListVehiclesRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_public_proto_msgTypes[25] + 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 ListVehiclesRequest.ProtoReflect.Descriptor instead. +func (*ListVehiclesRequest) Descriptor() ([]byte, []int) { + return file_api_public_proto_rawDescGZIP(), []int{25} +} + +func (x *ListVehiclesRequest) GetSystemId() string { + if x != nil { + return x.SystemId + } + return "" +} + +func (x *ListVehiclesRequest) GetSearchMode() ListVehiclesRequest_SearchMode { + if x != nil && x.SearchMode != nil { + return *x.SearchMode + } + return ListVehiclesRequest_ID +} + +func (x *ListVehiclesRequest) GetOnlyReturnSpecifiedIds() bool { + if x != nil { + return x.OnlyReturnSpecifiedIds + } + return false +} + +func (x *ListVehiclesRequest) GetId() []string { + if x != nil { + return x.Id + } + return nil +} + +func (x *ListVehiclesRequest) GetFirstId() string { + if x != nil && x.FirstId != nil { + return *x.FirstId + } + return "" +} + +func (x *ListVehiclesRequest) GetLimit() int32 { + if x != nil && x.Limit != nil { + return *x.Limit + } + return 0 +} + +func (x *ListVehiclesRequest) GetMaxDistance() float64 { + if x != nil && x.MaxDistance != nil { + return *x.MaxDistance + } + return 0 +} + +func (x *ListVehiclesRequest) GetLatitude() float64 { + if x != nil && x.Latitude != nil { + return *x.Latitude + } + return 0 +} + +func (x *ListVehiclesRequest) GetLongitude() float64 { + if x != nil && x.Longitude != nil { + return *x.Longitude + } + return 0 +} + +type ListVehiclesReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // List of vehicles. + Vehicles []*Vehicle `protobuf:"bytes,1,rep,name=vehicles,proto3" json:"vehicles,omitempty"` + // ID of the next vehicle to return, if there are more results. + NextId *string `protobuf:"bytes,2,opt,name=next_id,json=nextId,proto3,oneof" json:"next_id,omitempty"` +} + +func (x *ListVehiclesReply) Reset() { + *x = ListVehiclesReply{} + if protoimpl.UnsafeEnabled { + mi := &file_api_public_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListVehiclesReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListVehiclesReply) ProtoMessage() {} + +func (x *ListVehiclesReply) ProtoReflect() protoreflect.Message { + mi := &file_api_public_proto_msgTypes[26] + 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 ListVehiclesReply.ProtoReflect.Descriptor instead. +func (*ListVehiclesReply) Descriptor() ([]byte, []int) { + return file_api_public_proto_rawDescGZIP(), []int{26} +} + +func (x *ListVehiclesReply) GetVehicles() []*Vehicle { + if x != nil { + return x.Vehicles + } + return nil +} + +func (x *ListVehiclesReply) GetNextId() string { + if x != nil && x.NextId != nil { + return *x.NextId + } + return "" +} + +type GetVehicleRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // ID of the system the vehicle is in. + // + // This is a URL parameter in the HTTP API. + SystemId string `protobuf:"bytes,1,opt,name=system_id,json=systemId,proto3" json:"system_id,omitempty"` + // ID of the vehicle. + // + // This is a URL parameter in the HTTP API. + VehicleId string `protobuf:"bytes,2,opt,name=vehicle_id,json=vehicleId,proto3" json:"vehicle_id,omitempty"` +} + +func (x *GetVehicleRequest) Reset() { + *x = GetVehicleRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_public_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetVehicleRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetVehicleRequest) ProtoMessage() {} + +func (x *GetVehicleRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_public_proto_msgTypes[27] + 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 GetVehicleRequest.ProtoReflect.Descriptor instead. +func (*GetVehicleRequest) Descriptor() ([]byte, []int) { + return file_api_public_proto_rawDescGZIP(), []int{27} +} + +func (x *GetVehicleRequest) GetSystemId() string { + if x != nil { + return x.SystemId + } + return "" +} + +func (x *GetVehicleRequest) GetVehicleId() string { + if x != nil { + return x.VehicleId + } + return "" +} + // The System resource. type System struct { state protoimpl.MessageState @@ -2184,7 +2648,7 @@ type System struct { func (x *System) Reset() { *x = System{} if protoimpl.UnsafeEnabled { - mi := &file_api_public_proto_msgTypes[25] + mi := &file_api_public_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2197,7 +2661,7 @@ func (x *System) String() string { func (*System) ProtoMessage() {} func (x *System) ProtoReflect() protoreflect.Message { - mi := &file_api_public_proto_msgTypes[25] + mi := &file_api_public_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2210,7 +2674,7 @@ func (x *System) ProtoReflect() protoreflect.Message { // Deprecated: Use System.ProtoReflect.Descriptor instead. func (*System) Descriptor() ([]byte, []int) { - return file_api_public_proto_rawDescGZIP(), []int{25} + return file_api_public_proto_rawDescGZIP(), []int{28} } func (x *System) GetId() string { @@ -2289,7 +2753,7 @@ type Resource struct { func (x *Resource) Reset() { *x = Resource{} if protoimpl.UnsafeEnabled { - mi := &file_api_public_proto_msgTypes[26] + mi := &file_api_public_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2302,7 +2766,7 @@ func (x *Resource) String() string { func (*Resource) ProtoMessage() {} func (x *Resource) ProtoReflect() protoreflect.Message { - mi := &file_api_public_proto_msgTypes[26] + mi := &file_api_public_proto_msgTypes[29] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2315,7 +2779,7 @@ func (x *Resource) ProtoReflect() protoreflect.Message { // Deprecated: Use Resource.ProtoReflect.Descriptor instead. func (*Resource) Descriptor() ([]byte, []int) { - return file_api_public_proto_rawDescGZIP(), []int{26} + return file_api_public_proto_rawDescGZIP(), []int{29} } func (x *Resource) GetPath() string { @@ -2348,7 +2812,7 @@ type ChildResources struct { func (x *ChildResources) Reset() { *x = ChildResources{} if protoimpl.UnsafeEnabled { - mi := &file_api_public_proto_msgTypes[27] + mi := &file_api_public_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2361,7 +2825,7 @@ func (x *ChildResources) String() string { func (*ChildResources) ProtoMessage() {} func (x *ChildResources) ProtoReflect() protoreflect.Message { - mi := &file_api_public_proto_msgTypes[27] + mi := &file_api_public_proto_msgTypes[30] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2374,7 +2838,7 @@ func (x *ChildResources) ProtoReflect() protoreflect.Message { // Deprecated: Use ChildResources.ProtoReflect.Descriptor instead. func (*ChildResources) Descriptor() ([]byte, []int) { - return file_api_public_proto_rawDescGZIP(), []int{27} + return file_api_public_proto_rawDescGZIP(), []int{30} } func (x *ChildResources) GetCount() int64 { @@ -2460,7 +2924,7 @@ type Stop struct { func (x *Stop) Reset() { *x = Stop{} if protoimpl.UnsafeEnabled { - mi := &file_api_public_proto_msgTypes[28] + mi := &file_api_public_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2473,7 +2937,7 @@ func (x *Stop) String() string { func (*Stop) ProtoMessage() {} func (x *Stop) ProtoReflect() protoreflect.Message { - mi := &file_api_public_proto_msgTypes[28] + mi := &file_api_public_proto_msgTypes[31] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2486,7 +2950,7 @@ func (x *Stop) ProtoReflect() protoreflect.Message { // Deprecated: Use Stop.ProtoReflect.Descriptor instead. func (*Stop) Descriptor() ([]byte, []int) { - return file_api_public_proto_rawDescGZIP(), []int{28} + return file_api_public_proto_rawDescGZIP(), []int{31} } func (x *Stop) GetId() string { @@ -2672,7 +3136,7 @@ type StopTime struct { func (x *StopTime) Reset() { *x = StopTime{} if protoimpl.UnsafeEnabled { - mi := &file_api_public_proto_msgTypes[29] + mi := &file_api_public_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2685,7 +3149,7 @@ func (x *StopTime) String() string { func (*StopTime) ProtoMessage() {} func (x *StopTime) ProtoReflect() protoreflect.Message { - mi := &file_api_public_proto_msgTypes[29] + mi := &file_api_public_proto_msgTypes[32] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2698,7 +3162,7 @@ func (x *StopTime) ProtoReflect() protoreflect.Message { // Deprecated: Use StopTime.ProtoReflect.Descriptor instead. func (*StopTime) Descriptor() ([]byte, []int) { - return file_api_public_proto_rawDescGZIP(), []int{29} + return file_api_public_proto_rawDescGZIP(), []int{32} } func (x *StopTime) GetStop() *Stop_Reference { @@ -2778,7 +3242,7 @@ type Trip struct { func (x *Trip) Reset() { *x = Trip{} if protoimpl.UnsafeEnabled { - mi := &file_api_public_proto_msgTypes[30] + mi := &file_api_public_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2791,7 +3255,7 @@ func (x *Trip) String() string { func (*Trip) ProtoMessage() {} func (x *Trip) ProtoReflect() protoreflect.Message { - mi := &file_api_public_proto_msgTypes[30] + mi := &file_api_public_proto_msgTypes[33] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2804,7 +3268,7 @@ func (x *Trip) ProtoReflect() protoreflect.Message { // Deprecated: Use Trip.ProtoReflect.Descriptor instead. func (*Trip) Descriptor() ([]byte, []int) { - return file_api_public_proto_rawDescGZIP(), []int{30} + return file_api_public_proto_rawDescGZIP(), []int{33} } func (x *Trip) GetId() string { @@ -2856,16 +3320,49 @@ func (x *Trip) GetStopTimes() []*StopTime { return nil } +// The Vehicle resource. +// +// This resource corresponds to the [vehicle position type in the GTFS static +// specification](https://developers.google.com/transit/gtfs-realtime/reference#message-vehicleposition). type Vehicle struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + + // A unique ID for the vehicle. + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // A reference to the vehicle's trip. + Trip *Trip_Reference `protobuf:"bytes,2,opt,name=trip,proto3,oneof" json:"trip,omitempty"` + // The vehicle's current latitude. + Latitude *float64 `protobuf:"fixed64,3,opt,name=latitude,proto3,oneof" json:"latitude,omitempty"` + // The vehicle's current longitude. + Longitude *float64 `protobuf:"fixed64,4,opt,name=longitude,proto3,oneof" json:"longitude,omitempty"` + // The vehicle's current bearing. + Bearing *float32 `protobuf:"fixed32,5,opt,name=bearing,proto3,oneof" json:"bearing,omitempty"` + // The vehicle's current odometer reading. + Odometer *float64 `protobuf:"fixed64,6,opt,name=odometer,proto3,oneof" json:"odometer,omitempty"` + // The vehicle's current speed. + Speed *float32 `protobuf:"fixed32,7,opt,name=speed,proto3,oneof" json:"speed,omitempty"` + // The stop sequence index of the vehicle's current stop. + StopSequence *int32 `protobuf:"varint,8,opt,name=stop_sequence,json=stopSequence,proto3,oneof" json:"stop_sequence,omitempty"` + // A reference to the vehicle's current stop. + Stop *Stop_Reference `protobuf:"bytes,9,opt,name=stop,proto3,oneof" json:"stop,omitempty"` + // The vehicle's current status. + CurrentStatus *Vehicle_CurrentStatus `protobuf:"varint,10,opt,name=current_status,json=currentStatus,proto3,enum=Vehicle_CurrentStatus,oneof" json:"current_status,omitempty"` + // The timestamp of the last update to the vehicle's position. + UpdatedAt *int64 `protobuf:"varint,11,opt,name=updated_at,json=updatedAt,proto3,oneof" json:"updated_at,omitempty"` + // The vehicle's current congestion level. + CongestionLevel Vehicle_CongestionLevel `protobuf:"varint,12,opt,name=congestion_level,json=congestionLevel,proto3,enum=Vehicle_CongestionLevel" json:"congestion_level,omitempty"` + // The vehicle's current occupancy status. + OccupancyStatus *Vehicle_OccupancyStatus `protobuf:"varint,13,opt,name=occupancy_status,json=occupancyStatus,proto3,enum=Vehicle_OccupancyStatus,oneof" json:"occupancy_status,omitempty"` + // The percentage of seats occupied. + OccupancyPercentage *int32 `protobuf:"varint,14,opt,name=occupancy_percentage,json=occupancyPercentage,proto3,oneof" json:"occupancy_percentage,omitempty"` } func (x *Vehicle) Reset() { *x = Vehicle{} if protoimpl.UnsafeEnabled { - mi := &file_api_public_proto_msgTypes[31] + mi := &file_api_public_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2878,7 +3375,7 @@ func (x *Vehicle) String() string { func (*Vehicle) ProtoMessage() {} func (x *Vehicle) ProtoReflect() protoreflect.Message { - mi := &file_api_public_proto_msgTypes[31] + mi := &file_api_public_proto_msgTypes[34] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2886,12 +3383,110 @@ func (x *Vehicle) ProtoReflect() protoreflect.Message { } return ms } - return mi.MessageOf(x) + return mi.MessageOf(x) +} + +// Deprecated: Use Vehicle.ProtoReflect.Descriptor instead. +func (*Vehicle) Descriptor() ([]byte, []int) { + return file_api_public_proto_rawDescGZIP(), []int{34} +} + +func (x *Vehicle) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Vehicle) GetTrip() *Trip_Reference { + if x != nil { + return x.Trip + } + return nil +} + +func (x *Vehicle) GetLatitude() float64 { + if x != nil && x.Latitude != nil { + return *x.Latitude + } + return 0 +} + +func (x *Vehicle) GetLongitude() float64 { + if x != nil && x.Longitude != nil { + return *x.Longitude + } + return 0 +} + +func (x *Vehicle) GetBearing() float32 { + if x != nil && x.Bearing != nil { + return *x.Bearing + } + return 0 +} + +func (x *Vehicle) GetOdometer() float64 { + if x != nil && x.Odometer != nil { + return *x.Odometer + } + return 0 +} + +func (x *Vehicle) GetSpeed() float32 { + if x != nil && x.Speed != nil { + return *x.Speed + } + return 0 +} + +func (x *Vehicle) GetStopSequence() int32 { + if x != nil && x.StopSequence != nil { + return *x.StopSequence + } + return 0 +} + +func (x *Vehicle) GetStop() *Stop_Reference { + if x != nil { + return x.Stop + } + return nil +} + +func (x *Vehicle) GetCurrentStatus() Vehicle_CurrentStatus { + if x != nil && x.CurrentStatus != nil { + return *x.CurrentStatus + } + return Vehicle_INCOMING_AT +} + +func (x *Vehicle) GetUpdatedAt() int64 { + if x != nil && x.UpdatedAt != nil { + return *x.UpdatedAt + } + return 0 +} + +func (x *Vehicle) GetCongestionLevel() Vehicle_CongestionLevel { + if x != nil { + return x.CongestionLevel + } + return Vehicle_UNKNOWN_CONGESTION_LEVEL } -// Deprecated: Use Vehicle.ProtoReflect.Descriptor instead. -func (*Vehicle) Descriptor() ([]byte, []int) { - return file_api_public_proto_rawDescGZIP(), []int{31} +func (x *Vehicle) GetOccupancyStatus() Vehicle_OccupancyStatus { + if x != nil && x.OccupancyStatus != nil { + return *x.OccupancyStatus + } + return Vehicle_EMPTY +} + +func (x *Vehicle) GetOccupancyPercentage() int32 { + if x != nil && x.OccupancyPercentage != nil { + return *x.OccupancyPercentage + } + return 0 } // The Route resource. @@ -2965,7 +3560,7 @@ type Route struct { func (x *Route) Reset() { *x = Route{} if protoimpl.UnsafeEnabled { - mi := &file_api_public_proto_msgTypes[32] + mi := &file_api_public_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2978,7 +3573,7 @@ func (x *Route) String() string { func (*Route) ProtoMessage() {} func (x *Route) ProtoReflect() protoreflect.Message { - mi := &file_api_public_proto_msgTypes[32] + mi := &file_api_public_proto_msgTypes[35] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2991,7 +3586,7 @@ func (x *Route) ProtoReflect() protoreflect.Message { // Deprecated: Use Route.ProtoReflect.Descriptor instead. func (*Route) Descriptor() ([]byte, []int) { - return file_api_public_proto_rawDescGZIP(), []int{32} + return file_api_public_proto_rawDescGZIP(), []int{35} } func (x *Route) GetId() string { @@ -3145,7 +3740,7 @@ type Feed struct { func (x *Feed) Reset() { *x = Feed{} if protoimpl.UnsafeEnabled { - mi := &file_api_public_proto_msgTypes[33] + mi := &file_api_public_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3158,7 +3753,7 @@ func (x *Feed) String() string { func (*Feed) ProtoMessage() {} func (x *Feed) ProtoReflect() protoreflect.Message { - mi := &file_api_public_proto_msgTypes[33] + mi := &file_api_public_proto_msgTypes[36] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3171,7 +3766,7 @@ func (x *Feed) ProtoReflect() protoreflect.Message { // Deprecated: Use Feed.ProtoReflect.Descriptor instead. func (*Feed) Descriptor() ([]byte, []int) { - return file_api_public_proto_rawDescGZIP(), []int{33} + return file_api_public_proto_rawDescGZIP(), []int{36} } func (x *Feed) GetId() string { @@ -3268,7 +3863,7 @@ type Agency struct { func (x *Agency) Reset() { *x = Agency{} if protoimpl.UnsafeEnabled { - mi := &file_api_public_proto_msgTypes[34] + mi := &file_api_public_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3281,7 +3876,7 @@ func (x *Agency) String() string { func (*Agency) ProtoMessage() {} func (x *Agency) ProtoReflect() protoreflect.Message { - mi := &file_api_public_proto_msgTypes[34] + mi := &file_api_public_proto_msgTypes[37] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3294,7 +3889,7 @@ func (x *Agency) ProtoReflect() protoreflect.Message { // Deprecated: Use Agency.ProtoReflect.Descriptor instead. func (*Agency) Descriptor() ([]byte, []int) { - return file_api_public_proto_rawDescGZIP(), []int{34} + return file_api_public_proto_rawDescGZIP(), []int{37} } func (x *Agency) GetId() string { @@ -3425,7 +4020,7 @@ type Alert struct { func (x *Alert) Reset() { *x = Alert{} if protoimpl.UnsafeEnabled { - mi := &file_api_public_proto_msgTypes[35] + mi := &file_api_public_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3438,7 +4033,7 @@ func (x *Alert) String() string { func (*Alert) ProtoMessage() {} func (x *Alert) ProtoReflect() protoreflect.Message { - mi := &file_api_public_proto_msgTypes[35] + mi := &file_api_public_proto_msgTypes[38] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3451,7 +4046,7 @@ func (x *Alert) ProtoReflect() protoreflect.Message { // Deprecated: Use Alert.ProtoReflect.Descriptor instead. func (*Alert) Descriptor() ([]byte, []int) { - return file_api_public_proto_rawDescGZIP(), []int{35} + return file_api_public_proto_rawDescGZIP(), []int{38} } func (x *Alert) GetId() string { @@ -3541,7 +4136,7 @@ type Transfer struct { func (x *Transfer) Reset() { *x = Transfer{} if protoimpl.UnsafeEnabled { - mi := &file_api_public_proto_msgTypes[36] + mi := &file_api_public_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3554,7 +4149,7 @@ func (x *Transfer) String() string { func (*Transfer) ProtoMessage() {} func (x *Transfer) ProtoReflect() protoreflect.Message { - mi := &file_api_public_proto_msgTypes[36] + mi := &file_api_public_proto_msgTypes[39] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3567,7 +4162,7 @@ func (x *Transfer) ProtoReflect() protoreflect.Message { // Deprecated: Use Transfer.ProtoReflect.Descriptor instead. func (*Transfer) Descriptor() ([]byte, []int) { - return file_api_public_proto_rawDescGZIP(), []int{36} + return file_api_public_proto_rawDescGZIP(), []int{39} } func (x *Transfer) GetFromStop() *Stop_Reference { @@ -3622,7 +4217,7 @@ type EntrypointReply_TransiterDetails struct { func (x *EntrypointReply_TransiterDetails) Reset() { *x = EntrypointReply_TransiterDetails{} if protoimpl.UnsafeEnabled { - mi := &file_api_public_proto_msgTypes[37] + mi := &file_api_public_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3635,7 +4230,7 @@ func (x *EntrypointReply_TransiterDetails) String() string { func (*EntrypointReply_TransiterDetails) ProtoMessage() {} func (x *EntrypointReply_TransiterDetails) ProtoReflect() protoreflect.Message { - mi := &file_api_public_proto_msgTypes[37] + mi := &file_api_public_proto_msgTypes[40] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3693,7 +4288,7 @@ type EntrypointReply_TransiterDetails_Build struct { func (x *EntrypointReply_TransiterDetails_Build) Reset() { *x = EntrypointReply_TransiterDetails_Build{} if protoimpl.UnsafeEnabled { - mi := &file_api_public_proto_msgTypes[38] + mi := &file_api_public_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3706,7 +4301,7 @@ func (x *EntrypointReply_TransiterDetails_Build) String() string { func (*EntrypointReply_TransiterDetails_Build) ProtoMessage() {} func (x *EntrypointReply_TransiterDetails_Build) ProtoReflect() protoreflect.Message { - mi := &file_api_public_proto_msgTypes[38] + mi := &file_api_public_proto_msgTypes[41] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3770,7 +4365,7 @@ type System_Reference struct { func (x *System_Reference) Reset() { *x = System_Reference{} if protoimpl.UnsafeEnabled { - mi := &file_api_public_proto_msgTypes[39] + mi := &file_api_public_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3783,7 +4378,7 @@ func (x *System_Reference) String() string { func (*System_Reference) ProtoMessage() {} func (x *System_Reference) ProtoReflect() protoreflect.Message { - mi := &file_api_public_proto_msgTypes[39] + mi := &file_api_public_proto_msgTypes[42] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3796,7 +4391,7 @@ func (x *System_Reference) ProtoReflect() protoreflect.Message { // Deprecated: Use System_Reference.ProtoReflect.Descriptor instead. func (*System_Reference) Descriptor() ([]byte, []int) { - return file_api_public_proto_rawDescGZIP(), []int{25, 0} + return file_api_public_proto_rawDescGZIP(), []int{28, 0} } func (x *System_Reference) GetId() string { @@ -3833,7 +4428,7 @@ type Stop_ServiceMap struct { func (x *Stop_ServiceMap) Reset() { *x = Stop_ServiceMap{} if protoimpl.UnsafeEnabled { - mi := &file_api_public_proto_msgTypes[40] + mi := &file_api_public_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3846,7 +4441,7 @@ func (x *Stop_ServiceMap) String() string { func (*Stop_ServiceMap) ProtoMessage() {} func (x *Stop_ServiceMap) ProtoReflect() protoreflect.Message { - mi := &file_api_public_proto_msgTypes[40] + mi := &file_api_public_proto_msgTypes[43] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3859,7 +4454,7 @@ func (x *Stop_ServiceMap) ProtoReflect() protoreflect.Message { // Deprecated: Use Stop_ServiceMap.ProtoReflect.Descriptor instead. func (*Stop_ServiceMap) Descriptor() ([]byte, []int) { - return file_api_public_proto_rawDescGZIP(), []int{28, 0} + return file_api_public_proto_rawDescGZIP(), []int{31, 0} } func (x *Stop_ServiceMap) GetConfigId() string { @@ -3895,7 +4490,7 @@ type Stop_HeadsignRule struct { func (x *Stop_HeadsignRule) Reset() { *x = Stop_HeadsignRule{} if protoimpl.UnsafeEnabled { - mi := &file_api_public_proto_msgTypes[41] + mi := &file_api_public_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3908,7 +4503,7 @@ func (x *Stop_HeadsignRule) String() string { func (*Stop_HeadsignRule) ProtoMessage() {} func (x *Stop_HeadsignRule) ProtoReflect() protoreflect.Message { - mi := &file_api_public_proto_msgTypes[41] + mi := &file_api_public_proto_msgTypes[44] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3921,7 +4516,7 @@ func (x *Stop_HeadsignRule) ProtoReflect() protoreflect.Message { // Deprecated: Use Stop_HeadsignRule.ProtoReflect.Descriptor instead. func (*Stop_HeadsignRule) Descriptor() ([]byte, []int) { - return file_api_public_proto_rawDescGZIP(), []int{28, 1} + return file_api_public_proto_rawDescGZIP(), []int{31, 1} } func (x *Stop_HeadsignRule) GetStop() *Stop_Reference { @@ -3967,7 +4562,7 @@ type Stop_Reference struct { func (x *Stop_Reference) Reset() { *x = Stop_Reference{} if protoimpl.UnsafeEnabled { - mi := &file_api_public_proto_msgTypes[42] + mi := &file_api_public_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3980,7 +4575,7 @@ func (x *Stop_Reference) String() string { func (*Stop_Reference) ProtoMessage() {} func (x *Stop_Reference) ProtoReflect() protoreflect.Message { - mi := &file_api_public_proto_msgTypes[42] + mi := &file_api_public_proto_msgTypes[45] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3993,7 +4588,7 @@ func (x *Stop_Reference) ProtoReflect() protoreflect.Message { // Deprecated: Use Stop_Reference.ProtoReflect.Descriptor instead. func (*Stop_Reference) Descriptor() ([]byte, []int) { - return file_api_public_proto_rawDescGZIP(), []int{28, 2} + return file_api_public_proto_rawDescGZIP(), []int{31, 2} } func (x *Stop_Reference) GetId() string { @@ -4040,7 +4635,7 @@ type StopTime_EstimatedTime struct { func (x *StopTime_EstimatedTime) Reset() { *x = StopTime_EstimatedTime{} if protoimpl.UnsafeEnabled { - mi := &file_api_public_proto_msgTypes[43] + mi := &file_api_public_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4053,7 +4648,7 @@ func (x *StopTime_EstimatedTime) String() string { func (*StopTime_EstimatedTime) ProtoMessage() {} func (x *StopTime_EstimatedTime) ProtoReflect() protoreflect.Message { - mi := &file_api_public_proto_msgTypes[43] + mi := &file_api_public_proto_msgTypes[46] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4066,7 +4661,7 @@ func (x *StopTime_EstimatedTime) ProtoReflect() protoreflect.Message { // Deprecated: Use StopTime_EstimatedTime.ProtoReflect.Descriptor instead. func (*StopTime_EstimatedTime) Descriptor() ([]byte, []int) { - return file_api_public_proto_rawDescGZIP(), []int{29, 0} + return file_api_public_proto_rawDescGZIP(), []int{32, 0} } func (x *StopTime_EstimatedTime) GetTime() int64 { @@ -4107,7 +4702,7 @@ type Trip_Reference struct { func (x *Trip_Reference) Reset() { *x = Trip_Reference{} if protoimpl.UnsafeEnabled { - mi := &file_api_public_proto_msgTypes[44] + mi := &file_api_public_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4120,7 +4715,7 @@ func (x *Trip_Reference) String() string { func (*Trip_Reference) ProtoMessage() {} func (x *Trip_Reference) ProtoReflect() protoreflect.Message { - mi := &file_api_public_proto_msgTypes[44] + mi := &file_api_public_proto_msgTypes[47] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4133,7 +4728,7 @@ func (x *Trip_Reference) ProtoReflect() protoreflect.Message { // Deprecated: Use Trip_Reference.ProtoReflect.Descriptor instead. func (*Trip_Reference) Descriptor() ([]byte, []int) { - return file_api_public_proto_rawDescGZIP(), []int{30, 0} + return file_api_public_proto_rawDescGZIP(), []int{33, 0} } func (x *Trip_Reference) GetId() string { @@ -4184,13 +4779,14 @@ type Vehicle_Reference struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Resource *Resource `protobuf:"bytes,2,opt,name=resource,proto3" json:"resource,omitempty"` } func (x *Vehicle_Reference) Reset() { *x = Vehicle_Reference{} if protoimpl.UnsafeEnabled { - mi := &file_api_public_proto_msgTypes[45] + mi := &file_api_public_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4203,7 +4799,7 @@ func (x *Vehicle_Reference) String() string { func (*Vehicle_Reference) ProtoMessage() {} func (x *Vehicle_Reference) ProtoReflect() protoreflect.Message { - mi := &file_api_public_proto_msgTypes[45] + mi := &file_api_public_proto_msgTypes[48] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4216,7 +4812,7 @@ func (x *Vehicle_Reference) ProtoReflect() protoreflect.Message { // Deprecated: Use Vehicle_Reference.ProtoReflect.Descriptor instead. func (*Vehicle_Reference) Descriptor() ([]byte, []int) { - return file_api_public_proto_rawDescGZIP(), []int{31, 0} + return file_api_public_proto_rawDescGZIP(), []int{34, 0} } func (x *Vehicle_Reference) GetId() string { @@ -4226,6 +4822,13 @@ func (x *Vehicle_Reference) GetId() string { return "" } +func (x *Vehicle_Reference) GetResource() *Resource { + if x != nil { + return x.Resource + } + return nil +} + // Message describing the service maps view in routes. // // See the service maps documentation for more information on this @@ -4246,7 +4849,7 @@ type Route_ServiceMap struct { func (x *Route_ServiceMap) Reset() { *x = Route_ServiceMap{} if protoimpl.UnsafeEnabled { - mi := &file_api_public_proto_msgTypes[46] + mi := &file_api_public_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4259,7 +4862,7 @@ func (x *Route_ServiceMap) String() string { func (*Route_ServiceMap) ProtoMessage() {} func (x *Route_ServiceMap) ProtoReflect() protoreflect.Message { - mi := &file_api_public_proto_msgTypes[46] + mi := &file_api_public_proto_msgTypes[49] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4272,7 +4875,7 @@ func (x *Route_ServiceMap) ProtoReflect() protoreflect.Message { // Deprecated: Use Route_ServiceMap.ProtoReflect.Descriptor instead. func (*Route_ServiceMap) Descriptor() ([]byte, []int) { - return file_api_public_proto_rawDescGZIP(), []int{32, 0} + return file_api_public_proto_rawDescGZIP(), []int{35, 0} } func (x *Route_ServiceMap) GetConfigId() string { @@ -4304,7 +4907,7 @@ type Route_Reference struct { func (x *Route_Reference) Reset() { *x = Route_Reference{} if protoimpl.UnsafeEnabled { - mi := &file_api_public_proto_msgTypes[47] + mi := &file_api_public_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4317,7 +4920,7 @@ func (x *Route_Reference) String() string { func (*Route_Reference) ProtoMessage() {} func (x *Route_Reference) ProtoReflect() protoreflect.Message { - mi := &file_api_public_proto_msgTypes[47] + mi := &file_api_public_proto_msgTypes[50] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4330,7 +4933,7 @@ func (x *Route_Reference) ProtoReflect() protoreflect.Message { // Deprecated: Use Route_Reference.ProtoReflect.Descriptor instead. func (*Route_Reference) Descriptor() ([]byte, []int) { - return file_api_public_proto_rawDescGZIP(), []int{32, 1} + return file_api_public_proto_rawDescGZIP(), []int{35, 1} } func (x *Route_Reference) GetId() string { @@ -4375,7 +4978,7 @@ type Feed_Reference struct { func (x *Feed_Reference) Reset() { *x = Feed_Reference{} if protoimpl.UnsafeEnabled { - mi := &file_api_public_proto_msgTypes[48] + mi := &file_api_public_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4388,7 +4991,7 @@ func (x *Feed_Reference) String() string { func (*Feed_Reference) ProtoMessage() {} func (x *Feed_Reference) ProtoReflect() protoreflect.Message { - mi := &file_api_public_proto_msgTypes[48] + mi := &file_api_public_proto_msgTypes[51] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4401,7 +5004,7 @@ func (x *Feed_Reference) ProtoReflect() protoreflect.Message { // Deprecated: Use Feed_Reference.ProtoReflect.Descriptor instead. func (*Feed_Reference) Descriptor() ([]byte, []int) { - return file_api_public_proto_rawDescGZIP(), []int{33, 0} + return file_api_public_proto_rawDescGZIP(), []int{36, 0} } func (x *Feed_Reference) GetId() string { @@ -4440,7 +5043,7 @@ type Agency_Reference struct { func (x *Agency_Reference) Reset() { *x = Agency_Reference{} if protoimpl.UnsafeEnabled { - mi := &file_api_public_proto_msgTypes[49] + mi := &file_api_public_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4453,7 +5056,7 @@ func (x *Agency_Reference) String() string { func (*Agency_Reference) ProtoMessage() {} func (x *Agency_Reference) ProtoReflect() protoreflect.Message { - mi := &file_api_public_proto_msgTypes[49] + mi := &file_api_public_proto_msgTypes[52] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4466,7 +5069,7 @@ func (x *Agency_Reference) ProtoReflect() protoreflect.Message { // Deprecated: Use Agency_Reference.ProtoReflect.Descriptor instead. func (*Agency_Reference) Descriptor() ([]byte, []int) { - return file_api_public_proto_rawDescGZIP(), []int{34, 0} + return file_api_public_proto_rawDescGZIP(), []int{37, 0} } func (x *Agency_Reference) GetId() string { @@ -4517,7 +5120,7 @@ type Alert_ActivePeriod struct { func (x *Alert_ActivePeriod) Reset() { *x = Alert_ActivePeriod{} if protoimpl.UnsafeEnabled { - mi := &file_api_public_proto_msgTypes[50] + mi := &file_api_public_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4530,7 +5133,7 @@ func (x *Alert_ActivePeriod) String() string { func (*Alert_ActivePeriod) ProtoMessage() {} func (x *Alert_ActivePeriod) ProtoReflect() protoreflect.Message { - mi := &file_api_public_proto_msgTypes[50] + mi := &file_api_public_proto_msgTypes[53] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4543,7 +5146,7 @@ func (x *Alert_ActivePeriod) ProtoReflect() protoreflect.Message { // Deprecated: Use Alert_ActivePeriod.ProtoReflect.Descriptor instead. func (*Alert_ActivePeriod) Descriptor() ([]byte, []int) { - return file_api_public_proto_rawDescGZIP(), []int{35, 0} + return file_api_public_proto_rawDescGZIP(), []int{38, 0} } func (x *Alert_ActivePeriod) GetStartsAt() int64 { @@ -4577,7 +5180,7 @@ type Alert_Text struct { func (x *Alert_Text) Reset() { *x = Alert_Text{} if protoimpl.UnsafeEnabled { - mi := &file_api_public_proto_msgTypes[51] + mi := &file_api_public_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4590,7 +5193,7 @@ func (x *Alert_Text) String() string { func (*Alert_Text) ProtoMessage() {} func (x *Alert_Text) ProtoReflect() protoreflect.Message { - mi := &file_api_public_proto_msgTypes[51] + mi := &file_api_public_proto_msgTypes[54] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4603,7 +5206,7 @@ func (x *Alert_Text) ProtoReflect() protoreflect.Message { // Deprecated: Use Alert_Text.ProtoReflect.Descriptor instead. func (*Alert_Text) Descriptor() ([]byte, []int) { - return file_api_public_proto_rawDescGZIP(), []int{35, 1} + return file_api_public_proto_rawDescGZIP(), []int{38, 1} } func (x *Alert_Text) GetText() string { @@ -4636,7 +5239,7 @@ type Alert_Reference struct { func (x *Alert_Reference) Reset() { *x = Alert_Reference{} if protoimpl.UnsafeEnabled { - mi := &file_api_public_proto_msgTypes[52] + mi := &file_api_public_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4649,7 +5252,7 @@ func (x *Alert_Reference) String() string { func (*Alert_Reference) ProtoMessage() {} func (x *Alert_Reference) ProtoReflect() protoreflect.Message { - mi := &file_api_public_proto_msgTypes[52] + mi := &file_api_public_proto_msgTypes[55] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4662,7 +5265,7 @@ func (x *Alert_Reference) ProtoReflect() protoreflect.Message { // Deprecated: Use Alert_Reference.ProtoReflect.Descriptor instead. func (*Alert_Reference) Descriptor() ([]byte, []int) { - return file_api_public_proto_rawDescGZIP(), []int{35, 2} + return file_api_public_proto_rawDescGZIP(), []int{38, 2} } func (x *Alert_Reference) GetId() string { @@ -4886,541 +5489,670 @@ var file_api_public_proto_rawDesc = []byte{ 0x65, 0x72, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x27, 0x0a, 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, - 0x73, 0x22, 0x88, 0x04, 0x0a, 0x06, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x0e, 0x0a, 0x02, + 0x73, 0x22, 0xe2, 0x03, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x65, 0x68, 0x69, 0x63, 0x6c, + 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x79, 0x73, + 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x79, + 0x73, 0x74, 0x65, 0x6d, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x0b, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, + 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x56, 0x65, 0x68, 0x69, 0x63, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x4d, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x0a, + 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x4d, 0x6f, 0x64, 0x65, 0x88, 0x01, 0x01, 0x12, 0x39, 0x0a, + 0x19, 0x6f, 0x6e, 0x6c, 0x79, 0x5f, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x73, 0x70, 0x65, + 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x16, 0x6f, 0x6e, 0x6c, 0x79, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x53, 0x70, 0x65, 0x63, + 0x69, 0x66, 0x69, 0x65, 0x64, 0x49, 0x64, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x08, 0x66, 0x69, 0x72, 0x73, + 0x74, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x07, 0x66, 0x69, + 0x72, 0x73, 0x74, 0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, + 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x48, 0x02, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, + 0x88, 0x01, 0x01, 0x12, 0x26, 0x0a, 0x0c, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x69, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x01, 0x48, 0x03, 0x52, 0x0b, 0x6d, 0x61, 0x78, + 0x44, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, 0x6c, + 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x01, 0x48, 0x04, 0x52, + 0x08, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x88, 0x01, 0x01, 0x12, 0x21, 0x0a, 0x09, + 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x01, 0x48, + 0x05, 0x52, 0x09, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x88, 0x01, 0x01, 0x22, + 0x22, 0x0a, 0x0a, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x06, 0x0a, + 0x02, 0x49, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x49, 0x53, 0x54, 0x41, 0x4e, 0x43, + 0x45, 0x10, 0x01, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x6d, + 0x6f, 0x64, 0x65, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x69, 0x64, + 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x6d, + 0x61, 0x78, 0x5f, 0x64, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x42, 0x0b, 0x0a, 0x09, 0x5f, + 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x6c, 0x6f, 0x6e, + 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x22, 0x63, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x65, + 0x68, 0x69, 0x63, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x24, 0x0a, 0x08, 0x76, + 0x65, 0x68, 0x69, 0x63, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, + 0x56, 0x65, 0x68, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x08, 0x76, 0x65, 0x68, 0x69, 0x63, 0x6c, 0x65, + 0x73, 0x12, 0x1c, 0x0a, 0x07, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, 0x6e, 0x65, 0x78, 0x74, 0x49, 0x64, 0x88, 0x01, 0x01, 0x42, + 0x0a, 0x0a, 0x08, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x69, 0x64, 0x22, 0x4f, 0x0a, 0x11, 0x47, + 0x65, 0x74, 0x56, 0x65, 0x68, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x49, 0x64, 0x12, 0x1d, 0x0a, + 0x0a, 0x76, 0x65, 0x68, 0x69, 0x63, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x76, 0x65, 0x68, 0x69, 0x63, 0x6c, 0x65, 0x49, 0x64, 0x22, 0x88, 0x04, 0x0a, + 0x06, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x25, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x0e, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2b, 0x0a, 0x08, 0x61, 0x67, + 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, + 0x68, 0x69, 0x6c, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x08, 0x61, + 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x05, 0x66, 0x65, 0x65, 0x64, 0x73, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x05, 0x66, 0x65, 0x65, 0x64, 0x73, 0x12, 0x27, + 0x0a, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, + 0x2e, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, + 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x70, 0x73, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x70, 0x73, 0x12, 0x2d, + 0x0a, 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x73, 0x52, 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x1a, 0x42, 0x0a, + 0x09, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x25, 0x0a, 0x08, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x22, 0x74, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x55, + 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x49, 0x4e, 0x53, 0x54, + 0x41, 0x4c, 0x4c, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x41, 0x43, 0x54, 0x49, + 0x56, 0x45, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4c, 0x4c, 0x5f, + 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x55, 0x50, 0x44, 0x41, + 0x54, 0x49, 0x4e, 0x47, 0x10, 0x04, 0x12, 0x11, 0x0a, 0x0d, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, + 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x05, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x45, 0x4c, + 0x45, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x06, 0x22, 0x40, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x17, 0x0a, 0x04, 0x68, 0x72, 0x65, 0x66, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x68, 0x72, 0x65, 0x66, 0x88, 0x01, 0x01, + 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x68, 0x72, 0x65, 0x66, 0x22, 0x48, 0x0a, 0x0e, 0x43, 0x68, 0x69, + 0x6c, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x12, 0x17, 0x0a, 0x04, 0x68, 0x72, 0x65, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, + 0x00, 0x52, 0x04, 0x68, 0x72, 0x65, 0x66, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x68, + 0x72, 0x65, 0x66, 0x22, 0x9d, 0x0b, 0x0a, 0x04, 0x53, 0x74, 0x6f, 0x70, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x25, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0e, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, - 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, - 0x2b, 0x0a, 0x08, 0x61, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x73, 0x52, 0x08, 0x61, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x05, - 0x66, 0x65, 0x65, 0x64, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x68, - 0x69, 0x6c, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x05, 0x66, 0x65, - 0x65, 0x64, 0x73, 0x12, 0x27, 0x0a, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x73, 0x52, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x05, - 0x73, 0x74, 0x6f, 0x70, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x68, - 0x69, 0x6c, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x05, 0x73, 0x74, - 0x6f, 0x70, 0x73, 0x12, 0x2d, 0x0a, 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, - 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, - 0x72, 0x73, 0x1a, 0x42, 0x0a, 0x09, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, - 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, - 0x25, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x09, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x74, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0e, 0x0a, - 0x0a, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4c, 0x4c, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0a, 0x0a, - 0x06, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x49, 0x4e, 0x53, - 0x54, 0x41, 0x4c, 0x4c, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x03, 0x12, 0x0c, 0x0a, - 0x08, 0x55, 0x50, 0x44, 0x41, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x04, 0x12, 0x11, 0x0a, 0x0d, 0x55, - 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x05, 0x12, 0x0c, - 0x0a, 0x08, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x06, 0x22, 0x40, 0x0a, 0x08, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x17, 0x0a, 0x04, - 0x68, 0x72, 0x65, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x68, 0x72, - 0x65, 0x66, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x68, 0x72, 0x65, 0x66, 0x22, 0x48, - 0x0a, 0x0e, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, - 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x17, 0x0a, 0x04, 0x68, 0x72, 0x65, 0x66, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x68, 0x72, 0x65, 0x66, 0x88, 0x01, 0x01, 0x42, - 0x07, 0x0a, 0x05, 0x5f, 0x68, 0x72, 0x65, 0x66, 0x22, 0x9d, 0x0b, 0x0a, 0x04, 0x53, 0x74, 0x6f, - 0x70, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, + 0x72, 0x63, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x52, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x17, + 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, + 0x63, 0x6f, 0x64, 0x65, 0x88, 0x01, 0x01, 0x12, 0x17, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, + 0x12, 0x25, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x1c, 0x0a, 0x07, 0x7a, 0x6f, 0x6e, 0x65, 0x5f, + 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x48, 0x03, 0x52, 0x06, 0x7a, 0x6f, 0x6e, 0x65, + 0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, + 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x01, 0x48, 0x04, 0x52, 0x08, 0x6c, 0x61, 0x74, 0x69, 0x74, + 0x75, 0x64, 0x65, 0x88, 0x01, 0x01, 0x12, 0x21, 0x0a, 0x09, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, + 0x75, 0x64, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x01, 0x48, 0x05, 0x52, 0x09, 0x6c, 0x6f, 0x6e, + 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x88, 0x01, 0x01, 0x12, 0x15, 0x0a, 0x03, 0x75, 0x72, 0x6c, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x48, 0x06, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x88, 0x01, 0x01, + 0x12, 0x1e, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0a, + 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x12, 0x35, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x6f, 0x70, 0x18, + 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x2e, 0x52, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x48, 0x07, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x53, 0x74, 0x6f, 0x70, 0x88, 0x01, 0x01, 0x12, 0x30, 0x0a, 0x0b, 0x63, 0x68, 0x69, 0x6c, 0x64, + 0x5f, 0x73, 0x74, 0x6f, 0x70, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x53, + 0x74, 0x6f, 0x70, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x0a, 0x63, + 0x68, 0x69, 0x6c, 0x64, 0x53, 0x74, 0x6f, 0x70, 0x73, 0x12, 0x1f, 0x0a, 0x08, 0x74, 0x69, 0x6d, + 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x48, 0x08, 0x52, 0x08, 0x74, + 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x88, 0x01, 0x01, 0x12, 0x34, 0x0a, 0x13, 0x77, 0x68, + 0x65, 0x65, 0x6c, 0x63, 0x68, 0x61, 0x69, 0x72, 0x5f, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, + 0x67, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x48, 0x09, 0x52, 0x12, 0x77, 0x68, 0x65, 0x65, 0x6c, + 0x63, 0x68, 0x61, 0x69, 0x72, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x88, 0x01, 0x01, + 0x12, 0x28, 0x0a, 0x0d, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x63, 0x6f, 0x64, + 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x48, 0x0a, 0x52, 0x0c, 0x70, 0x6c, 0x61, 0x74, 0x66, + 0x6f, 0x72, 0x6d, 0x43, 0x6f, 0x64, 0x65, 0x88, 0x01, 0x01, 0x12, 0x33, 0x0a, 0x0c, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6d, 0x61, 0x70, 0x73, 0x18, 0x11, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x10, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4d, + 0x61, 0x70, 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x73, 0x12, + 0x28, 0x0a, 0x06, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x18, 0x12, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x10, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x52, 0x06, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x12, 0x28, 0x0a, 0x0a, 0x73, 0x74, 0x6f, + 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x18, 0x13, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x09, 0x2e, + 0x53, 0x74, 0x6f, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x09, 0x73, 0x74, 0x6f, 0x70, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x12, 0x27, 0x0a, 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, + 0x18, 0x14, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, + 0x72, 0x52, 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x12, 0x39, 0x0a, 0x0e, + 0x68, 0x65, 0x61, 0x64, 0x73, 0x69, 0x67, 0x6e, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x15, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x2e, 0x48, 0x65, 0x61, 0x64, + 0x73, 0x69, 0x67, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0d, 0x68, 0x65, 0x61, 0x64, 0x73, 0x69, + 0x67, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x1a, 0x53, 0x0a, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x4d, 0x61, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x49, 0x64, 0x12, 0x28, 0x0a, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x52, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x1a, 0x90, 0x01, 0x0a, + 0x0c, 0x48, 0x65, 0x61, 0x64, 0x73, 0x69, 0x67, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x23, 0x0a, + 0x04, 0x73, 0x74, 0x6f, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x53, 0x74, + 0x6f, 0x70, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x04, 0x73, 0x74, + 0x6f, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x19, + 0x0a, 0x05, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, + 0x05, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x88, 0x01, 0x01, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x65, 0x61, + 0x64, 0x73, 0x69, 0x67, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x65, 0x61, + 0x64, 0x73, 0x69, 0x67, 0x6e, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x1a, + 0x8f, 0x01, 0x0a, 0x09, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x25, 0x0a, + 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x09, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x52, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, + 0x17, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x22, 0x58, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x54, 0x4f, + 0x50, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x54, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, + 0x12, 0x14, 0x0a, 0x10, 0x45, 0x4e, 0x54, 0x52, 0x41, 0x4e, 0x43, 0x45, 0x5f, 0x4f, 0x52, 0x5f, + 0x45, 0x58, 0x49, 0x54, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x49, + 0x43, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x10, 0x03, 0x12, 0x11, 0x0a, 0x0d, 0x42, 0x4f, 0x41, 0x52, + 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x41, 0x52, 0x45, 0x41, 0x10, 0x04, 0x42, 0x07, 0x0a, 0x05, 0x5f, + 0x63, 0x6f, 0x64, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x0e, 0x0a, + 0x0c, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x0a, 0x0a, + 0x08, 0x5f, 0x7a, 0x6f, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x6c, 0x61, + 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x6c, 0x6f, 0x6e, 0x67, 0x69, + 0x74, 0x75, 0x64, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x75, 0x72, 0x6c, 0x42, 0x0e, 0x0a, 0x0c, + 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x6f, 0x70, 0x42, 0x0b, 0x0a, 0x09, + 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x42, 0x16, 0x0a, 0x14, 0x5f, 0x77, 0x68, + 0x65, 0x65, 0x6c, 0x63, 0x68, 0x61, 0x69, 0x72, 0x5f, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, + 0x67, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x63, + 0x6f, 0x64, 0x65, 0x22, 0xde, 0x03, 0x0a, 0x08, 0x53, 0x74, 0x6f, 0x70, 0x54, 0x69, 0x6d, 0x65, + 0x12, 0x23, 0x0a, 0x04, 0x73, 0x74, 0x6f, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, + 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, + 0x04, 0x73, 0x74, 0x6f, 0x70, 0x12, 0x23, 0x0a, 0x04, 0x74, 0x72, 0x69, 0x70, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x54, 0x72, 0x69, 0x70, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x52, 0x04, 0x74, 0x72, 0x69, 0x70, 0x12, 0x31, 0x0a, 0x07, 0x61, 0x72, + 0x72, 0x69, 0x76, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x53, 0x74, + 0x6f, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x2e, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, + 0x54, 0x69, 0x6d, 0x65, 0x52, 0x07, 0x61, 0x72, 0x72, 0x69, 0x76, 0x61, 0x6c, 0x12, 0x35, 0x0a, + 0x09, 0x64, 0x65, 0x70, 0x61, 0x72, 0x74, 0x75, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x17, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x2e, 0x45, 0x73, 0x74, 0x69, + 0x6d, 0x61, 0x74, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x09, 0x64, 0x65, 0x70, 0x61, 0x72, + 0x74, 0x75, 0x72, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x12, 0x23, 0x0a, 0x0d, + 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x0c, 0x73, 0x74, 0x6f, 0x70, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, + 0x65, 0x12, 0x1f, 0x0a, 0x08, 0x68, 0x65, 0x61, 0x64, 0x73, 0x69, 0x67, 0x6e, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x08, 0x68, 0x65, 0x61, 0x64, 0x73, 0x69, 0x67, 0x6e, 0x88, + 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x09, 0x48, 0x01, 0x52, 0x05, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x88, 0x01, 0x01, 0x1a, 0x8d, 0x01, + 0x0a, 0x0d, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, + 0x17, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, + 0x04, 0x74, 0x69, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x64, 0x65, 0x6c, 0x61, + 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x48, 0x01, 0x52, 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79, + 0x88, 0x01, 0x01, 0x12, 0x25, 0x0a, 0x0b, 0x75, 0x6e, 0x63, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6e, + 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x48, 0x02, 0x52, 0x0b, 0x75, 0x6e, 0x63, 0x65, + 0x72, 0x74, 0x61, 0x69, 0x6e, 0x74, 0x79, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x42, 0x0e, 0x0a, + 0x0c, 0x5f, 0x75, 0x6e, 0x63, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6e, 0x74, 0x79, 0x42, 0x0b, 0x0a, + 0x09, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x73, 0x69, 0x67, 0x6e, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x74, + 0x72, 0x61, 0x63, 0x6b, 0x22, 0xa6, 0x04, 0x0a, 0x04, 0x54, 0x72, 0x69, 0x70, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x25, 0x0a, + 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x09, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x12, 0x26, 0x0a, 0x05, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x05, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x22, 0x0a, 0x0a, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, + 0x48, 0x00, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x41, 0x74, 0x88, 0x01, 0x01, + 0x12, 0x31, 0x0a, 0x07, 0x76, 0x65, 0x68, 0x69, 0x63, 0x6c, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x12, 0x2e, 0x56, 0x65, 0x68, 0x69, 0x63, 0x6c, 0x65, 0x2e, 0x52, 0x65, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x48, 0x01, 0x52, 0x07, 0x76, 0x65, 0x68, 0x69, 0x63, 0x6c, 0x65, + 0x88, 0x01, 0x01, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x64, 0x69, 0x72, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x0a, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x53, 0x74, 0x6f, + 0x70, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x09, 0x73, 0x74, 0x6f, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x1a, 0xff, 0x01, 0x0a, 0x09, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x0e, + 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x25, + 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x09, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x26, 0x0a, 0x05, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x05, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x31, 0x0a, + 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x31, 0x0a, 0x07, 0x76, 0x65, 0x68, 0x69, 0x63, 0x6c, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x12, 0x2e, 0x56, 0x65, 0x68, 0x69, 0x63, 0x6c, 0x65, 0x2e, 0x52, 0x65, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x48, 0x00, 0x52, 0x07, 0x76, 0x65, 0x68, 0x69, 0x63, 0x6c, 0x65, + 0x88, 0x01, 0x01, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x64, 0x69, 0x72, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x76, 0x65, 0x68, 0x69, 0x63, + 0x6c, 0x65, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x61, + 0x74, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x76, 0x65, 0x68, 0x69, 0x63, 0x6c, 0x65, 0x22, 0xd1, 0x09, + 0x0a, 0x07, 0x56, 0x65, 0x68, 0x69, 0x63, 0x6c, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x28, 0x0a, 0x04, 0x74, 0x72, 0x69, + 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x54, 0x72, 0x69, 0x70, 0x2e, 0x52, + 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x48, 0x00, 0x52, 0x04, 0x74, 0x72, 0x69, 0x70, + 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x01, 0x48, 0x01, 0x52, 0x08, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, + 0x65, 0x88, 0x01, 0x01, 0x12, 0x21, 0x0a, 0x09, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x48, 0x02, 0x52, 0x09, 0x6c, 0x6f, 0x6e, 0x67, 0x69, + 0x74, 0x75, 0x64, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, 0x07, 0x62, 0x65, 0x61, 0x72, 0x69, + 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x02, 0x48, 0x03, 0x52, 0x07, 0x62, 0x65, 0x61, 0x72, + 0x69, 0x6e, 0x67, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, 0x6f, 0x64, 0x6f, 0x6d, 0x65, 0x74, + 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x01, 0x48, 0x04, 0x52, 0x08, 0x6f, 0x64, 0x6f, 0x6d, + 0x65, 0x74, 0x65, 0x72, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x73, 0x70, 0x65, 0x65, 0x64, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x02, 0x48, 0x05, 0x52, 0x05, 0x73, 0x70, 0x65, 0x65, 0x64, 0x88, + 0x01, 0x01, 0x12, 0x28, 0x0a, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x73, 0x65, 0x71, 0x75, 0x65, + 0x6e, 0x63, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x48, 0x06, 0x52, 0x0c, 0x73, 0x74, 0x6f, + 0x70, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x88, 0x01, 0x01, 0x12, 0x28, 0x0a, 0x04, + 0x73, 0x74, 0x6f, 0x70, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x53, 0x74, 0x6f, + 0x70, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x48, 0x07, 0x52, 0x04, 0x73, + 0x74, 0x6f, 0x70, 0x88, 0x01, 0x01, 0x12, 0x42, 0x0a, 0x0e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, + 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, + 0x2e, 0x56, 0x65, 0x68, 0x69, 0x63, 0x6c, 0x65, 0x2e, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x48, 0x08, 0x52, 0x0d, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, + 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x88, 0x01, 0x01, 0x12, 0x22, 0x0a, 0x0a, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x48, 0x09, + 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x88, 0x01, 0x01, 0x12, 0x43, + 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x65, 0x76, + 0x65, 0x6c, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x56, 0x65, 0x68, 0x69, 0x63, + 0x6c, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x65, 0x76, + 0x65, 0x6c, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x65, + 0x76, 0x65, 0x6c, 0x12, 0x48, 0x0a, 0x10, 0x6f, 0x63, 0x63, 0x75, 0x70, 0x61, 0x6e, 0x63, 0x79, + 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, + 0x56, 0x65, 0x68, 0x69, 0x63, 0x6c, 0x65, 0x2e, 0x4f, 0x63, 0x63, 0x75, 0x70, 0x61, 0x6e, 0x63, + 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x48, 0x0a, 0x52, 0x0f, 0x6f, 0x63, 0x63, 0x75, 0x70, + 0x61, 0x6e, 0x63, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x88, 0x01, 0x01, 0x12, 0x36, 0x0a, + 0x14, 0x6f, 0x63, 0x63, 0x75, 0x70, 0x61, 0x6e, 0x63, 0x79, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, + 0x6e, 0x74, 0x61, 0x67, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x05, 0x48, 0x0b, 0x52, 0x13, 0x6f, + 0x63, 0x63, 0x75, 0x70, 0x61, 0x6e, 0x63, 0x79, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, + 0x67, 0x65, 0x88, 0x01, 0x01, 0x1a, 0x42, 0x0a, 0x09, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, + 0x69, 0x64, 0x12, 0x25, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, + 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x43, 0x0a, 0x0d, 0x43, 0x75, 0x72, + 0x72, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0f, 0x0a, 0x0b, 0x49, 0x4e, + 0x43, 0x4f, 0x4d, 0x49, 0x4e, 0x47, 0x5f, 0x41, 0x54, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x53, + 0x54, 0x4f, 0x50, 0x50, 0x45, 0x44, 0x5f, 0x41, 0x54, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x49, + 0x4e, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, 0x5f, 0x54, 0x4f, 0x10, 0x02, 0x22, 0x7d, + 0x0a, 0x0f, 0x43, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x65, 0x76, 0x65, + 0x6c, 0x12, 0x1c, 0x0a, 0x18, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x43, 0x4f, 0x4e, + 0x47, 0x45, 0x53, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x10, 0x00, 0x12, + 0x14, 0x0a, 0x10, 0x52, 0x55, 0x4e, 0x4e, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x4d, 0x4f, 0x4f, 0x54, + 0x48, 0x4c, 0x59, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x53, 0x54, 0x4f, 0x50, 0x5f, 0x41, 0x4e, + 0x44, 0x5f, 0x47, 0x4f, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x43, 0x4f, 0x4e, 0x47, 0x45, 0x53, + 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x03, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x45, 0x56, 0x45, 0x52, 0x45, + 0x5f, 0x43, 0x4f, 0x4e, 0x47, 0x45, 0x53, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x04, 0x22, 0xaf, 0x01, + 0x0a, 0x0f, 0x4f, 0x63, 0x63, 0x75, 0x70, 0x61, 0x6e, 0x63, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x4d, 0x50, 0x54, 0x59, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, + 0x4d, 0x41, 0x4e, 0x59, 0x5f, 0x53, 0x45, 0x41, 0x54, 0x53, 0x5f, 0x41, 0x56, 0x41, 0x49, 0x4c, + 0x41, 0x42, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x46, 0x45, 0x57, 0x5f, 0x53, 0x45, + 0x41, 0x54, 0x53, 0x5f, 0x41, 0x56, 0x41, 0x49, 0x4c, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x02, 0x12, + 0x16, 0x0a, 0x12, 0x53, 0x54, 0x41, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x52, 0x4f, 0x4f, 0x4d, + 0x5f, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x03, 0x12, 0x1e, 0x0a, 0x1a, 0x43, 0x52, 0x55, 0x53, 0x48, + 0x45, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x52, 0x4f, 0x4f, 0x4d, + 0x5f, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x04, 0x12, 0x08, 0x0a, 0x04, 0x46, 0x55, 0x4c, 0x4c, 0x10, + 0x05, 0x12, 0x1c, 0x0a, 0x18, 0x4e, 0x4f, 0x54, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x49, + 0x4e, 0x47, 0x5f, 0x50, 0x41, 0x53, 0x53, 0x45, 0x4e, 0x47, 0x45, 0x52, 0x53, 0x10, 0x06, 0x42, + 0x07, 0x0a, 0x05, 0x5f, 0x74, 0x72, 0x69, 0x70, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x6c, 0x61, 0x74, + 0x69, 0x74, 0x75, 0x64, 0x65, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, + 0x75, 0x64, 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x62, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x42, + 0x0b, 0x0a, 0x09, 0x5f, 0x6f, 0x64, 0x6f, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x42, 0x08, 0x0a, 0x06, + 0x5f, 0x73, 0x70, 0x65, 0x65, 0x64, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x73, 0x74, 0x6f, 0x70, 0x5f, + 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x73, 0x74, 0x6f, + 0x70, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, + 0x5f, 0x61, 0x74, 0x42, 0x13, 0x0a, 0x11, 0x5f, 0x6f, 0x63, 0x63, 0x75, 0x70, 0x61, 0x6e, 0x63, + 0x79, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x17, 0x0a, 0x15, 0x5f, 0x6f, 0x63, 0x63, + 0x75, 0x70, 0x61, 0x6e, 0x63, 0x79, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, + 0x65, 0x22, 0xe4, 0x09, 0x0a, 0x05, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x25, 0x0a, 0x08, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x52, 0x65, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x22, 0x0a, + 0x0a, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x48, 0x00, 0x52, 0x09, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x88, 0x01, + 0x01, 0x12, 0x20, 0x0a, 0x09, 0x6c, 0x6f, 0x6e, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x08, 0x6c, 0x6f, 0x6e, 0x67, 0x4e, 0x61, 0x6d, 0x65, + 0x88, 0x01, 0x01, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x65, 0x78, + 0x74, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, + 0x65, 0x78, 0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x12, 0x25, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, + 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, + 0x15, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x48, 0x03, 0x52, 0x03, + 0x75, 0x72, 0x6c, 0x88, 0x01, 0x01, 0x12, 0x22, 0x0a, 0x0a, 0x73, 0x6f, 0x72, 0x74, 0x5f, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x48, 0x04, 0x52, 0x09, 0x73, 0x6f, + 0x72, 0x74, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x88, 0x01, 0x01, 0x12, 0x44, 0x0a, 0x11, 0x63, 0x6f, + 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x70, 0x69, 0x63, 0x6b, 0x75, 0x70, 0x18, + 0x0b, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x43, 0x6f, + 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x10, + 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x50, 0x69, 0x63, 0x6b, 0x75, 0x70, + 0x12, 0x47, 0x0a, 0x13, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x64, + 0x72, 0x6f, 0x70, 0x5f, 0x6f, 0x66, 0x66, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, + 0x52, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, + 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x11, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, + 0x75, 0x73, 0x44, 0x72, 0x6f, 0x70, 0x4f, 0x66, 0x66, 0x12, 0x1f, 0x0a, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0b, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x2e, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x61, 0x67, + 0x65, 0x6e, 0x63, 0x79, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x41, 0x67, 0x65, + 0x6e, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x06, 0x61, + 0x67, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x28, 0x0a, 0x06, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x18, + 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x2e, 0x52, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x06, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x12, + 0x30, 0x0a, 0x11, 0x65, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x61, + 0x64, 0x77, 0x61, 0x79, 0x18, 0x10, 0x20, 0x01, 0x28, 0x05, 0x48, 0x05, 0x52, 0x10, 0x65, 0x73, + 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, 0x48, 0x65, 0x61, 0x64, 0x77, 0x61, 0x79, 0x88, 0x01, + 0x01, 0x12, 0x34, 0x0a, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6d, 0x61, 0x70, + 0x73, 0x18, 0x11, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x2e, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x73, 0x1a, 0x50, 0x0a, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x4d, 0x61, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x49, 0x64, 0x12, 0x25, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x70, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x0f, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x70, 0x73, 0x1a, 0x83, 0x01, 0x0a, 0x09, 0x52, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x25, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x29, + 0x0a, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x52, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x22, + 0x5e, 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x12, 0x0b, 0x0a, 0x07, 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x45, 0x44, 0x10, 0x00, + 0x12, 0x0f, 0x0a, 0x0b, 0x4e, 0x4f, 0x54, 0x5f, 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x45, 0x44, 0x10, + 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x50, 0x48, 0x4f, 0x4e, 0x45, 0x5f, 0x41, 0x47, 0x45, 0x4e, 0x43, + 0x59, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x49, 0x4e, 0x41, 0x54, + 0x45, 0x5f, 0x57, 0x49, 0x54, 0x48, 0x5f, 0x44, 0x52, 0x49, 0x56, 0x45, 0x52, 0x10, 0x03, 0x22, + 0x9c, 0x01, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0e, 0x0a, 0x0a, 0x4c, 0x49, 0x47, 0x48, + 0x54, 0x5f, 0x52, 0x41, 0x49, 0x4c, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x55, 0x42, 0x57, + 0x41, 0x59, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x52, 0x41, 0x49, 0x4c, 0x10, 0x02, 0x12, 0x07, + 0x0a, 0x03, 0x42, 0x55, 0x53, 0x10, 0x03, 0x12, 0x09, 0x0a, 0x05, 0x46, 0x45, 0x52, 0x52, 0x59, + 0x10, 0x04, 0x12, 0x0e, 0x0a, 0x0a, 0x43, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x54, 0x52, 0x41, 0x4d, + 0x10, 0x05, 0x12, 0x0f, 0x0a, 0x0b, 0x41, 0x45, 0x52, 0x49, 0x41, 0x4c, 0x5f, 0x4c, 0x49, 0x46, + 0x54, 0x10, 0x06, 0x12, 0x0d, 0x0a, 0x09, 0x46, 0x55, 0x4e, 0x49, 0x43, 0x55, 0x4c, 0x41, 0x52, + 0x10, 0x07, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x52, 0x4f, 0x4c, 0x4c, 0x45, 0x59, 0x5f, 0x42, 0x55, + 0x53, 0x10, 0x0b, 0x12, 0x0c, 0x0a, 0x08, 0x4d, 0x4f, 0x4e, 0x4f, 0x52, 0x41, 0x49, 0x4c, 0x10, + 0x0c, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x64, 0x42, 0x0d, + 0x0a, 0x0b, 0x5f, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x0c, 0x0a, + 0x0a, 0x5f, 0x6c, 0x6f, 0x6e, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x06, 0x0a, 0x04, 0x5f, + 0x75, 0x72, 0x6c, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x73, 0x6f, 0x72, 0x74, 0x5f, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x65, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, + 0x5f, 0x68, 0x65, 0x61, 0x64, 0x77, 0x61, 0x79, 0x22, 0x9a, 0x04, 0x0a, 0x04, 0x46, 0x65, 0x65, + 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x25, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x06, 0x73, 0x79, 0x73, - 0x74, 0x65, 0x6d, 0x12, 0x17, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x48, 0x00, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x88, 0x01, 0x01, 0x12, 0x17, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x25, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x0b, 0x64, 0x65, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x1c, 0x0a, 0x07, - 0x7a, 0x6f, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x48, 0x03, 0x52, - 0x06, 0x7a, 0x6f, 0x6e, 0x65, 0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, 0x6c, 0x61, - 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x01, 0x48, 0x04, 0x52, 0x08, - 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x88, 0x01, 0x01, 0x12, 0x21, 0x0a, 0x09, 0x6c, - 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x01, 0x48, 0x05, - 0x52, 0x09, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x88, 0x01, 0x01, 0x12, 0x15, - 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x48, 0x06, 0x52, 0x03, 0x75, - 0x72, 0x6c, 0x88, 0x01, 0x01, 0x12, 0x1e, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0b, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x0a, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x35, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, - 0x73, 0x74, 0x6f, 0x70, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x53, 0x74, 0x6f, - 0x70, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x48, 0x07, 0x52, 0x0a, 0x70, - 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x6f, 0x70, 0x88, 0x01, 0x01, 0x12, 0x30, 0x0a, 0x0b, - 0x63, 0x68, 0x69, 0x6c, 0x64, 0x5f, 0x73, 0x74, 0x6f, 0x70, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x0f, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, - 0x63, 0x65, 0x52, 0x0a, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x53, 0x74, 0x6f, 0x70, 0x73, 0x12, 0x1f, - 0x0a, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, - 0x48, 0x08, 0x52, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x88, 0x01, 0x01, 0x12, - 0x34, 0x0a, 0x13, 0x77, 0x68, 0x65, 0x65, 0x6c, 0x63, 0x68, 0x61, 0x69, 0x72, 0x5f, 0x62, 0x6f, - 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x48, 0x09, 0x52, 0x12, - 0x77, 0x68, 0x65, 0x65, 0x6c, 0x63, 0x68, 0x61, 0x69, 0x72, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x69, - 0x6e, 0x67, 0x88, 0x01, 0x01, 0x12, 0x28, 0x0a, 0x0d, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, - 0x6d, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x48, 0x0a, 0x52, 0x0c, - 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x43, 0x6f, 0x64, 0x65, 0x88, 0x01, 0x01, 0x12, - 0x33, 0x0a, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6d, 0x61, 0x70, 0x73, 0x18, - 0x11, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x2e, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x4d, 0x61, 0x70, 0x73, 0x12, 0x28, 0x0a, 0x06, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x18, 0x12, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x2e, 0x52, 0x65, 0x66, - 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x06, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x12, 0x28, - 0x0a, 0x0a, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x18, 0x13, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x09, 0x73, - 0x74, 0x6f, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x12, 0x27, 0x0a, 0x09, 0x74, 0x72, 0x61, 0x6e, - 0x73, 0x66, 0x65, 0x72, 0x73, 0x18, 0x14, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x54, 0x72, - 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, - 0x73, 0x12, 0x39, 0x0a, 0x0e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x69, 0x67, 0x6e, 0x5f, 0x72, 0x75, - 0x6c, 0x65, 0x73, 0x18, 0x15, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x53, 0x74, 0x6f, 0x70, - 0x2e, 0x48, 0x65, 0x61, 0x64, 0x73, 0x69, 0x67, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0d, 0x68, - 0x65, 0x61, 0x64, 0x73, 0x69, 0x67, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x1a, 0x53, 0x0a, 0x0a, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, - 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x2e, - 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, - 0x73, 0x1a, 0x90, 0x01, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x64, 0x73, 0x69, 0x67, 0x6e, 0x52, 0x75, - 0x6c, 0x65, 0x12, 0x23, 0x0a, 0x04, 0x73, 0x74, 0x6f, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0f, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x52, 0x04, 0x73, 0x74, 0x6f, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, - 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, - 0x69, 0x74, 0x79, 0x12, 0x19, 0x0a, 0x05, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x88, 0x01, 0x01, 0x12, 0x1a, - 0x0a, 0x08, 0x68, 0x65, 0x61, 0x64, 0x73, 0x69, 0x67, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x68, 0x65, 0x61, 0x64, 0x73, 0x69, 0x67, 0x6e, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x74, - 0x72, 0x61, 0x63, 0x6b, 0x1a, 0x8f, 0x01, 0x0a, 0x09, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, - 0x63, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, - 0x69, 0x64, 0x12, 0x25, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, - 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x73, 0x79, 0x73, - 0x74, 0x65, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x53, 0x79, 0x73, 0x74, - 0x65, 0x6d, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x06, 0x73, 0x79, - 0x73, 0x74, 0x65, 0x6d, 0x12, 0x17, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, - 0x05, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x58, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, - 0x0a, 0x04, 0x53, 0x54, 0x4f, 0x50, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x54, 0x41, 0x54, - 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x45, 0x4e, 0x54, 0x52, 0x41, 0x4e, 0x43, - 0x45, 0x5f, 0x4f, 0x52, 0x5f, 0x45, 0x58, 0x49, 0x54, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x47, - 0x45, 0x4e, 0x45, 0x52, 0x49, 0x43, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x10, 0x03, 0x12, 0x11, 0x0a, - 0x0d, 0x42, 0x4f, 0x41, 0x52, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x41, 0x52, 0x45, 0x41, 0x10, 0x04, - 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x7a, 0x6f, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x42, 0x0b, - 0x0a, 0x09, 0x5f, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, - 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x75, 0x72, - 0x6c, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x6f, - 0x70, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x42, 0x16, - 0x0a, 0x14, 0x5f, 0x77, 0x68, 0x65, 0x65, 0x6c, 0x63, 0x68, 0x61, 0x69, 0x72, 0x5f, 0x62, 0x6f, - 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x70, 0x6c, 0x61, 0x74, 0x66, - 0x6f, 0x72, 0x6d, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x22, 0xde, 0x03, 0x0a, 0x08, 0x53, 0x74, 0x6f, - 0x70, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x04, 0x73, 0x74, 0x6f, 0x70, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, - 0x65, 0x6e, 0x63, 0x65, 0x52, 0x04, 0x73, 0x74, 0x6f, 0x70, 0x12, 0x23, 0x0a, 0x04, 0x74, 0x72, - 0x69, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x54, 0x72, 0x69, 0x70, 0x2e, - 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x04, 0x74, 0x72, 0x69, 0x70, 0x12, - 0x31, 0x0a, 0x07, 0x61, 0x72, 0x72, 0x69, 0x76, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x17, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x2e, 0x45, 0x73, 0x74, 0x69, - 0x6d, 0x61, 0x74, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x07, 0x61, 0x72, 0x72, 0x69, 0x76, - 0x61, 0x6c, 0x12, 0x35, 0x0a, 0x09, 0x64, 0x65, 0x70, 0x61, 0x72, 0x74, 0x75, 0x72, 0x65, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x54, 0x69, 0x6d, 0x65, - 0x2e, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x09, - 0x64, 0x65, 0x70, 0x61, 0x72, 0x74, 0x75, 0x72, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x75, 0x74, - 0x75, 0x72, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x66, 0x75, 0x74, 0x75, 0x72, - 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, - 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x73, 0x74, 0x6f, 0x70, 0x53, 0x65, - 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x08, 0x68, 0x65, 0x61, 0x64, 0x73, 0x69, - 0x67, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x08, 0x68, 0x65, 0x61, 0x64, - 0x73, 0x69, 0x67, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x74, 0x72, 0x61, 0x63, 0x6b, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x05, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x88, - 0x01, 0x01, 0x1a, 0x8d, 0x01, 0x0a, 0x0d, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, - 0x54, 0x69, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x03, 0x48, 0x00, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, - 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x48, 0x01, 0x52, 0x05, - 0x64, 0x65, 0x6c, 0x61, 0x79, 0x88, 0x01, 0x01, 0x12, 0x25, 0x0a, 0x0b, 0x75, 0x6e, 0x63, 0x65, - 0x72, 0x74, 0x61, 0x69, 0x6e, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x48, 0x02, 0x52, - 0x0b, 0x75, 0x6e, 0x63, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6e, 0x74, 0x79, 0x88, 0x01, 0x01, 0x42, - 0x07, 0x0a, 0x05, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x64, 0x65, 0x6c, - 0x61, 0x79, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x75, 0x6e, 0x63, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6e, - 0x74, 0x79, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x73, 0x69, 0x67, 0x6e, 0x42, - 0x08, 0x0a, 0x06, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x22, 0xa6, 0x04, 0x0a, 0x04, 0x54, 0x72, - 0x69, 0x70, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, - 0x69, 0x64, 0x12, 0x25, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, - 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x26, 0x0a, 0x05, 0x72, 0x6f, 0x75, - 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, - 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x05, 0x72, 0x6f, 0x75, 0x74, - 0x65, 0x12, 0x22, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, - 0x41, 0x74, 0x88, 0x01, 0x01, 0x12, 0x31, 0x0a, 0x07, 0x76, 0x65, 0x68, 0x69, 0x63, 0x6c, 0x65, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x56, 0x65, 0x68, 0x69, 0x63, 0x6c, 0x65, - 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x48, 0x01, 0x52, 0x07, 0x76, 0x65, - 0x68, 0x69, 0x63, 0x6c, 0x65, 0x88, 0x01, 0x01, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x72, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, - 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x0a, 0x73, - 0x74, 0x6f, 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x09, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x09, 0x73, 0x74, 0x6f, 0x70, - 0x54, 0x69, 0x6d, 0x65, 0x73, 0x1a, 0xff, 0x01, 0x0a, 0x09, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x02, 0x69, 0x64, 0x12, 0x25, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x26, 0x0a, 0x05, 0x72, 0x6f, - 0x75, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x52, 0x6f, 0x75, 0x74, - 0x65, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x05, 0x72, 0x6f, 0x75, - 0x74, 0x65, 0x12, 0x31, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x2e, 0x52, - 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x31, 0x0a, 0x07, 0x76, 0x65, 0x68, 0x69, 0x63, 0x6c, 0x65, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x56, 0x65, 0x68, 0x69, 0x63, 0x6c, 0x65, - 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x48, 0x00, 0x52, 0x07, 0x76, 0x65, - 0x68, 0x69, 0x63, 0x6c, 0x65, 0x88, 0x01, 0x01, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x72, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, - 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x42, 0x0a, 0x0a, 0x08, 0x5f, - 0x76, 0x65, 0x68, 0x69, 0x63, 0x6c, 0x65, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x73, 0x74, 0x61, 0x72, - 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x76, 0x65, 0x68, 0x69, 0x63, - 0x6c, 0x65, 0x22, 0x26, 0x0a, 0x07, 0x56, 0x65, 0x68, 0x69, 0x63, 0x6c, 0x65, 0x1a, 0x1b, 0x0a, - 0x09, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0xe4, 0x09, 0x0a, 0x05, 0x52, - 0x6f, 0x75, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x02, 0x69, 0x64, 0x12, 0x25, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x73, - 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x53, 0x79, - 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x06, - 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x22, 0x0a, 0x0a, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x09, 0x73, 0x68, - 0x6f, 0x72, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x20, 0x0a, 0x09, 0x6c, 0x6f, - 0x6e, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, - 0x08, 0x6c, 0x6f, 0x6e, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x14, 0x0a, 0x05, - 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, 0x6f, 0x6c, - 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x65, 0x78, 0x74, 0x43, 0x6f, 0x6c, 0x6f, - 0x72, 0x12, 0x25, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x15, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, - 0x09, 0x20, 0x01, 0x28, 0x09, 0x48, 0x03, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x88, 0x01, 0x01, 0x12, - 0x22, 0x0a, 0x0a, 0x73, 0x6f, 0x72, 0x74, 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x0a, 0x20, - 0x01, 0x28, 0x05, 0x48, 0x04, 0x52, 0x09, 0x73, 0x6f, 0x72, 0x74, 0x4f, 0x72, 0x64, 0x65, 0x72, - 0x88, 0x01, 0x01, 0x12, 0x44, 0x0a, 0x11, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, - 0x73, 0x5f, 0x70, 0x69, 0x63, 0x6b, 0x75, 0x70, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, - 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, - 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, - 0x6f, 0x75, 0x73, 0x50, 0x69, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x47, 0x0a, 0x13, 0x63, 0x6f, 0x6e, - 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x64, 0x72, 0x6f, 0x70, 0x5f, 0x6f, 0x66, 0x66, - 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x43, - 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, - 0x11, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x44, 0x72, 0x6f, 0x70, 0x4f, - 0x66, 0x66, 0x12, 0x1f, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x0b, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x61, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x0e, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x66, - 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x06, 0x61, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x28, - 0x0a, 0x06, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, - 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, - 0x52, 0x06, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x12, 0x30, 0x0a, 0x11, 0x65, 0x73, 0x74, 0x69, - 0x6d, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x77, 0x61, 0x79, 0x18, 0x10, 0x20, - 0x01, 0x28, 0x05, 0x48, 0x05, 0x52, 0x10, 0x65, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, - 0x48, 0x65, 0x61, 0x64, 0x77, 0x61, 0x79, 0x88, 0x01, 0x01, 0x12, 0x34, 0x0a, 0x0c, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6d, 0x61, 0x70, 0x73, 0x18, 0x11, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x11, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x4d, 0x61, 0x70, 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x73, - 0x1a, 0x50, 0x0a, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x12, 0x1b, - 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x05, 0x73, - 0x74, 0x6f, 0x70, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x53, 0x74, 0x6f, - 0x70, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x05, 0x73, 0x74, 0x6f, - 0x70, 0x73, 0x1a, 0x83, 0x01, 0x0a, 0x09, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, + 0x74, 0x65, 0x6d, 0x12, 0x29, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x5f, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x0c, 0x6c, + 0x61, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x73, 0x88, 0x01, 0x01, 0x12, 0x3e, + 0x0a, 0x19, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, + 0x6c, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x03, 0x48, 0x01, 0x52, 0x16, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x66, 0x75, 0x6c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x73, 0x88, 0x01, 0x01, 0x12, 0x38, + 0x0a, 0x16, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x48, 0x02, + 0x52, 0x13, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x4d, 0x73, 0x88, 0x01, 0x01, 0x12, 0x36, 0x0a, 0x15, 0x6c, 0x61, 0x73, 0x74, + 0x5f, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, + 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x48, 0x03, 0x52, 0x12, 0x6c, 0x61, 0x73, 0x74, 0x46, + 0x61, 0x69, 0x6c, 0x65, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x73, 0x88, 0x01, 0x01, + 0x1a, 0x6d, 0x0a, 0x09, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x25, 0x0a, + 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x09, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x52, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x42, + 0x11, 0x0a, 0x0f, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, + 0x6d, 0x73, 0x42, 0x1c, 0x0a, 0x1a, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x75, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x73, + 0x42, 0x19, 0x0a, 0x17, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x6b, 0x69, 0x70, 0x70, 0x65, + 0x64, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x73, 0x42, 0x18, 0x0a, 0x16, 0x5f, + 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x5f, 0x75, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x5f, 0x6d, 0x73, 0x22, 0xa9, 0x04, 0x0a, 0x06, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x25, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x06, 0x73, 0x79, 0x73, 0x74, - 0x65, 0x6d, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x22, 0x5e, 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x74, - 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x0b, 0x0a, 0x07, - 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x4e, 0x4f, 0x54, - 0x5f, 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x45, 0x44, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x50, 0x48, - 0x4f, 0x4e, 0x45, 0x5f, 0x41, 0x47, 0x45, 0x4e, 0x43, 0x59, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, - 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x49, 0x4e, 0x41, 0x54, 0x45, 0x5f, 0x57, 0x49, 0x54, 0x48, 0x5f, - 0x44, 0x52, 0x49, 0x56, 0x45, 0x52, 0x10, 0x03, 0x22, 0x9c, 0x01, 0x0a, 0x04, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x0e, 0x0a, 0x0a, 0x4c, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x52, 0x41, 0x49, 0x4c, 0x10, - 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x55, 0x42, 0x57, 0x41, 0x59, 0x10, 0x01, 0x12, 0x08, 0x0a, - 0x04, 0x52, 0x41, 0x49, 0x4c, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x42, 0x55, 0x53, 0x10, 0x03, - 0x12, 0x09, 0x0a, 0x05, 0x46, 0x45, 0x52, 0x52, 0x59, 0x10, 0x04, 0x12, 0x0e, 0x0a, 0x0a, 0x43, - 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x54, 0x52, 0x41, 0x4d, 0x10, 0x05, 0x12, 0x0f, 0x0a, 0x0b, 0x41, - 0x45, 0x52, 0x49, 0x41, 0x4c, 0x5f, 0x4c, 0x49, 0x46, 0x54, 0x10, 0x06, 0x12, 0x0d, 0x0a, 0x09, - 0x46, 0x55, 0x4e, 0x49, 0x43, 0x55, 0x4c, 0x41, 0x52, 0x10, 0x07, 0x12, 0x0f, 0x0a, 0x0b, 0x54, - 0x52, 0x4f, 0x4c, 0x4c, 0x45, 0x59, 0x5f, 0x42, 0x55, 0x53, 0x10, 0x0b, 0x12, 0x0c, 0x0a, 0x08, - 0x4d, 0x4f, 0x4e, 0x4f, 0x52, 0x41, 0x49, 0x4c, 0x10, 0x0c, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, - 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x64, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x73, 0x68, 0x6f, 0x72, - 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x6c, 0x6f, 0x6e, 0x67, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x75, 0x72, 0x6c, 0x42, 0x0d, 0x0a, 0x0b, - 0x5f, 0x73, 0x6f, 0x72, 0x74, 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x14, 0x0a, 0x12, 0x5f, - 0x65, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x77, 0x61, - 0x79, 0x22, 0x9a, 0x04, 0x0a, 0x04, 0x46, 0x65, 0x65, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x25, 0x0a, 0x08, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x12, 0x29, 0x0a, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x11, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, - 0x65, 0x6e, 0x63, 0x65, 0x52, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x29, 0x0a, 0x0e, - 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x73, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x4d, 0x73, 0x88, 0x01, 0x01, 0x12, 0x3e, 0x0a, 0x19, 0x6c, 0x61, 0x73, 0x74, 0x5f, - 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x5f, 0x6d, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x48, 0x01, 0x52, 0x16, 0x6c, 0x61, - 0x73, 0x74, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x4d, 0x73, 0x88, 0x01, 0x01, 0x12, 0x38, 0x0a, 0x16, 0x6c, 0x61, 0x73, 0x74, 0x5f, - 0x73, 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, - 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x48, 0x02, 0x52, 0x13, 0x6c, 0x61, 0x73, 0x74, 0x53, - 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x73, 0x88, 0x01, - 0x01, 0x12, 0x36, 0x0a, 0x15, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, - 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, - 0x48, 0x03, 0x52, 0x12, 0x6c, 0x61, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x4d, 0x73, 0x88, 0x01, 0x01, 0x1a, 0x6d, 0x0a, 0x09, 0x52, 0x65, 0x66, - 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x25, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x29, 0x0a, - 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, - 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, - 0x52, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x6c, 0x61, 0x73, - 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x73, 0x42, 0x1c, 0x0a, 0x1a, 0x5f, - 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x5f, - 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x73, 0x42, 0x19, 0x0a, 0x17, 0x5f, 0x6c, 0x61, - 0x73, 0x74, 0x5f, 0x73, 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x5f, 0x6d, 0x73, 0x42, 0x18, 0x0a, 0x16, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x66, 0x61, - 0x69, 0x6c, 0x65, 0x64, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x73, 0x22, 0xa9, - 0x04, 0x0a, 0x06, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x25, 0x0a, 0x08, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x12, 0x29, 0x0a, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x11, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x52, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, - 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, - 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x12, 0x1f, 0x0a, - 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x48, - 0x00, 0x52, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x88, 0x01, 0x01, 0x12, 0x19, - 0x0a, 0x05, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, - 0x05, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1e, 0x0a, 0x08, 0x66, 0x61, 0x72, - 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x07, 0x66, - 0x61, 0x72, 0x65, 0x55, 0x72, 0x6c, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x65, 0x6d, 0x61, - 0x69, 0x6c, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x48, 0x03, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, - 0x6c, 0x88, 0x01, 0x01, 0x12, 0x28, 0x0a, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x0b, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x66, - 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x28, - 0x0a, 0x06, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, - 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, - 0x52, 0x06, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x1a, 0x81, 0x01, 0x0a, 0x09, 0x52, 0x65, 0x66, - 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x25, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x29, 0x0a, - 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, - 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, - 0x52, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x0b, 0x0a, 0x09, - 0x5f, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x70, 0x68, - 0x6f, 0x6e, 0x65, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x66, 0x61, 0x72, 0x65, 0x5f, 0x75, 0x72, 0x6c, - 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0xea, 0x09, 0x0a, 0x05, 0x41, - 0x6c, 0x65, 0x72, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x02, 0x69, 0x64, 0x12, 0x25, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x73, - 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x53, 0x79, - 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x06, - 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x22, 0x0a, 0x05, 0x63, 0x61, 0x75, 0x73, 0x65, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0c, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x2e, 0x43, 0x61, - 0x75, 0x73, 0x65, 0x52, 0x05, 0x63, 0x61, 0x75, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x06, 0x65, 0x66, - 0x66, 0x65, 0x63, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x41, 0x6c, 0x65, - 0x72, 0x74, 0x2e, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x52, 0x06, 0x65, 0x66, 0x66, 0x65, 0x63, - 0x74, 0x12, 0x4c, 0x0a, 0x15, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x63, 0x74, - 0x69, 0x76, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x13, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x50, - 0x65, 0x72, 0x69, 0x6f, 0x64, 0x48, 0x00, 0x52, 0x13, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, - 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x88, 0x01, 0x01, 0x12, - 0x41, 0x0a, 0x12, 0x61, 0x6c, 0x6c, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x65, - 0x72, 0x69, 0x6f, 0x64, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x41, 0x6c, - 0x65, 0x72, 0x74, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, - 0x52, 0x10, 0x61, 0x6c, 0x6c, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x50, 0x65, 0x72, 0x69, 0x6f, - 0x64, 0x73, 0x12, 0x23, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x08, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x2e, 0x54, 0x65, 0x78, 0x74, 0x52, - 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x2d, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x41, - 0x6c, 0x65, 0x72, 0x74, 0x2e, 0x54, 0x65, 0x78, 0x74, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x0a, 0x20, + 0x65, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x69, 0x6d, 0x65, + 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x69, 0x6d, 0x65, + 0x7a, 0x6f, 0x6e, 0x65, 0x12, 0x1f, 0x0a, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, + 0x67, 0x65, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x05, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x88, 0x01, 0x01, + 0x12, 0x1e, 0x0a, 0x08, 0x66, 0x61, 0x72, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x09, 0x48, 0x02, 0x52, 0x07, 0x66, 0x61, 0x72, 0x65, 0x55, 0x72, 0x6c, 0x88, 0x01, 0x01, + 0x12, 0x19, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x48, + 0x03, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x88, 0x01, 0x01, 0x12, 0x28, 0x0a, 0x06, 0x72, + 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x52, 0x6f, + 0x75, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x06, 0x72, + 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x28, 0x0a, 0x06, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x18, + 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x2e, 0x52, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x06, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x1a, + 0x81, 0x01, 0x0a, 0x09, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x25, 0x0a, + 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x09, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x52, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, + 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x66, + 0x61, 0x72, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x65, 0x6d, 0x61, 0x69, + 0x6c, 0x22, 0xea, 0x09, 0x0a, 0x05, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x25, 0x0a, 0x08, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x52, 0x65, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x22, 0x0a, + 0x05, 0x63, 0x61, 0x75, 0x73, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0c, 0x2e, 0x41, + 0x6c, 0x65, 0x72, 0x74, 0x2e, 0x43, 0x61, 0x75, 0x73, 0x65, 0x52, 0x05, 0x63, 0x61, 0x75, 0x73, + 0x65, 0x12, 0x25, 0x0a, 0x06, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x0d, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x2e, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, + 0x52, 0x06, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x12, 0x4c, 0x0a, 0x15, 0x63, 0x75, 0x72, 0x72, + 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, + 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x2e, + 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x48, 0x00, 0x52, 0x13, + 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x50, 0x65, 0x72, + 0x69, 0x6f, 0x64, 0x88, 0x01, 0x01, 0x12, 0x41, 0x0a, 0x12, 0x61, 0x6c, 0x6c, 0x5f, 0x61, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x73, 0x18, 0x07, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x52, 0x10, 0x61, 0x6c, 0x6c, 0x41, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x73, 0x12, 0x23, 0x0a, 0x06, 0x68, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x41, 0x6c, 0x65, 0x72, + 0x74, 0x2e, 0x54, 0x65, 0x78, 0x74, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x2d, + 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x2e, 0x54, 0x65, 0x78, 0x74, - 0x52, 0x03, 0x75, 0x72, 0x6c, 0x1a, 0x68, 0x0a, 0x0c, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x50, - 0x65, 0x72, 0x69, 0x6f, 0x64, 0x12, 0x20, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x5f, - 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x08, 0x73, 0x74, 0x61, 0x72, - 0x74, 0x73, 0x41, 0x74, 0x88, 0x01, 0x01, 0x12, 0x1c, 0x0a, 0x07, 0x65, 0x6e, 0x64, 0x73, 0x5f, - 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x48, 0x01, 0x52, 0x06, 0x65, 0x6e, 0x64, 0x73, - 0x41, 0x74, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, - 0x5f, 0x61, 0x74, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x65, 0x6e, 0x64, 0x73, 0x5f, 0x61, 0x74, 0x1a, - 0x36, 0x0a, 0x04, 0x54, 0x65, 0x78, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x65, 0x78, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6c, - 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, - 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x1a, 0xb8, 0x01, 0x0a, 0x09, 0x52, 0x65, 0x66, 0x65, - 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x25, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x29, 0x0a, 0x06, - 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x53, - 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, - 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x22, 0x0a, 0x05, 0x63, 0x61, 0x75, 0x73, 0x65, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0c, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x2e, 0x43, - 0x61, 0x75, 0x73, 0x65, 0x52, 0x05, 0x63, 0x61, 0x75, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x06, 0x65, - 0x66, 0x66, 0x65, 0x63, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x41, 0x6c, - 0x65, 0x72, 0x74, 0x2e, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x52, 0x06, 0x65, 0x66, 0x66, 0x65, - 0x63, 0x74, 0x22, 0xd8, 0x01, 0x0a, 0x05, 0x43, 0x61, 0x75, 0x73, 0x65, 0x12, 0x11, 0x0a, 0x0d, - 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x43, 0x41, 0x55, 0x53, 0x45, 0x10, 0x00, 0x12, - 0x0f, 0x0a, 0x0b, 0x4f, 0x54, 0x48, 0x45, 0x52, 0x5f, 0x43, 0x41, 0x55, 0x53, 0x45, 0x10, 0x02, - 0x12, 0x15, 0x0a, 0x11, 0x54, 0x45, 0x43, 0x48, 0x4e, 0x49, 0x43, 0x41, 0x4c, 0x5f, 0x50, 0x52, - 0x4f, 0x42, 0x4c, 0x45, 0x4d, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x54, 0x52, 0x49, 0x4b, - 0x45, 0x10, 0x04, 0x12, 0x11, 0x0a, 0x0d, 0x44, 0x45, 0x4d, 0x4f, 0x4e, 0x53, 0x54, 0x52, 0x41, - 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x05, 0x12, 0x0c, 0x0a, 0x08, 0x41, 0x43, 0x43, 0x49, 0x44, 0x45, - 0x4e, 0x54, 0x10, 0x06, 0x12, 0x0b, 0x0a, 0x07, 0x48, 0x4f, 0x4c, 0x49, 0x44, 0x41, 0x59, 0x10, - 0x07, 0x12, 0x0b, 0x0a, 0x07, 0x57, 0x45, 0x41, 0x54, 0x48, 0x45, 0x52, 0x10, 0x08, 0x12, 0x0f, - 0x0a, 0x0b, 0x4d, 0x41, 0x49, 0x4e, 0x54, 0x45, 0x4e, 0x41, 0x4e, 0x43, 0x45, 0x10, 0x09, 0x12, - 0x10, 0x0a, 0x0c, 0x43, 0x4f, 0x4e, 0x53, 0x54, 0x52, 0x55, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x10, - 0x0a, 0x12, 0x13, 0x0a, 0x0f, 0x50, 0x4f, 0x4c, 0x49, 0x43, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, - 0x56, 0x49, 0x54, 0x59, 0x10, 0x0b, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x45, 0x44, 0x49, 0x43, 0x41, - 0x4c, 0x5f, 0x45, 0x4d, 0x45, 0x52, 0x47, 0x45, 0x4e, 0x43, 0x59, 0x10, 0x0c, 0x22, 0xdd, 0x01, - 0x0a, 0x06, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x0e, 0x55, 0x4e, 0x4b, 0x4e, - 0x4f, 0x57, 0x4e, 0x5f, 0x45, 0x46, 0x46, 0x45, 0x43, 0x54, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, - 0x4e, 0x4f, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, - 0x52, 0x45, 0x44, 0x55, 0x43, 0x45, 0x44, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x10, - 0x02, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x49, 0x47, 0x4e, 0x49, 0x46, 0x49, 0x43, 0x41, 0x4e, 0x54, - 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x53, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x54, - 0x4f, 0x55, 0x52, 0x10, 0x04, 0x12, 0x16, 0x0a, 0x12, 0x41, 0x44, 0x44, 0x49, 0x54, 0x49, 0x4f, - 0x4e, 0x41, 0x4c, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x10, 0x05, 0x12, 0x14, 0x0a, - 0x10, 0x4d, 0x4f, 0x44, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, - 0x45, 0x10, 0x06, 0x12, 0x10, 0x0a, 0x0c, 0x4f, 0x54, 0x48, 0x45, 0x52, 0x5f, 0x45, 0x46, 0x46, - 0x45, 0x43, 0x54, 0x10, 0x07, 0x12, 0x0e, 0x0a, 0x0a, 0x53, 0x54, 0x4f, 0x50, 0x5f, 0x4d, 0x4f, - 0x56, 0x45, 0x44, 0x10, 0x09, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x4f, 0x5f, 0x45, 0x46, 0x46, 0x45, - 0x43, 0x54, 0x10, 0x0a, 0x12, 0x17, 0x0a, 0x13, 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x49, 0x42, - 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x49, 0x53, 0x53, 0x55, 0x45, 0x10, 0x0b, 0x42, 0x18, 0x0a, - 0x16, 0x5f, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, - 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x22, 0xc3, 0x02, 0x0a, 0x08, 0x54, 0x72, 0x61, 0x6e, - 0x73, 0x66, 0x65, 0x72, 0x12, 0x2c, 0x0a, 0x09, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x73, 0x74, 0x6f, - 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x2e, 0x52, - 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x08, 0x66, 0x72, 0x6f, 0x6d, 0x53, 0x74, - 0x6f, 0x70, 0x12, 0x28, 0x0a, 0x07, 0x74, 0x6f, 0x5f, 0x73, 0x74, 0x6f, 0x70, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, - 0x65, 0x6e, 0x63, 0x65, 0x52, 0x06, 0x74, 0x6f, 0x53, 0x74, 0x6f, 0x70, 0x12, 0x22, 0x0a, 0x04, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0e, 0x2e, 0x54, 0x72, 0x61, - 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x12, 0x2f, 0x0a, 0x11, 0x6d, 0x69, 0x6e, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, - 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x0f, 0x6d, - 0x69, 0x6e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x88, 0x01, - 0x01, 0x12, 0x1f, 0x0a, 0x08, 0x64, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x05, 0x48, 0x01, 0x52, 0x08, 0x64, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x88, - 0x01, 0x01, 0x22, 0x46, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x52, 0x45, - 0x43, 0x4f, 0x4d, 0x4d, 0x45, 0x4e, 0x44, 0x45, 0x44, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x54, - 0x49, 0x4d, 0x45, 0x44, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x52, 0x45, 0x51, 0x55, 0x49, 0x52, - 0x45, 0x53, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x4e, 0x4f, 0x5f, - 0x50, 0x4f, 0x53, 0x53, 0x49, 0x42, 0x4c, 0x45, 0x10, 0x03, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x6d, - 0x69, 0x6e, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x5f, 0x74, 0x69, 0x6d, 0x65, - 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x64, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x32, 0xed, 0x0a, - 0x0a, 0x06, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x12, 0x3d, 0x0a, 0x0a, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x12, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x70, 0x6f, - 0x69, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x09, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x03, 0x12, 0x01, 0x2f, 0x12, 0x47, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x53, - 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x13, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x79, 0x73, - 0x74, 0x65, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x4c, 0x69, - 0x73, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x10, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0a, 0x12, 0x08, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, - 0x12, 0x45, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x11, 0x2e, - 0x47, 0x65, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x07, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x16, 0x12, 0x14, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2f, 0x7b, 0x73, 0x79, 0x73, - 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x5f, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x41, - 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x12, 0x14, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x67, - 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, - 0x79, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x12, 0x1d, 0x2f, 0x73, 0x79, 0x73, 0x74, - 0x65, 0x6d, 0x73, 0x2f, 0x7b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x7d, 0x2f, - 0x61, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x12, 0x5a, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x41, - 0x67, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x11, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, - 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x07, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x63, - 0x79, 0x22, 0x31, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2b, 0x12, 0x29, 0x2f, 0x73, 0x79, 0x73, 0x74, - 0x65, 0x6d, 0x73, 0x2f, 0x7b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x7d, 0x2f, - 0x61, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x2f, 0x7b, 0x61, 0x67, 0x65, 0x6e, 0x63, 0x79, - 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x53, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x6f, 0x70, - 0x73, 0x12, 0x11, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x6f, 0x70, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x6f, 0x70, 0x73, - 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, - 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2f, 0x7b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, - 0x69, 0x64, 0x7d, 0x2f, 0x73, 0x74, 0x6f, 0x70, 0x73, 0x12, 0x4f, 0x0a, 0x07, 0x47, 0x65, 0x74, - 0x53, 0x74, 0x6f, 0x70, 0x12, 0x0f, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x05, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x22, 0x2c, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x26, 0x12, 0x24, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2f, 0x7b, + 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, + 0x03, 0x75, 0x72, 0x6c, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x41, 0x6c, 0x65, + 0x72, 0x74, 0x2e, 0x54, 0x65, 0x78, 0x74, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x1a, 0x68, 0x0a, 0x0c, + 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x12, 0x20, 0x0a, 0x09, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x5f, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x48, + 0x00, 0x52, 0x08, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x41, 0x74, 0x88, 0x01, 0x01, 0x12, 0x1c, + 0x0a, 0x07, 0x65, 0x6e, 0x64, 0x73, 0x5f, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x48, + 0x01, 0x52, 0x06, 0x65, 0x6e, 0x64, 0x73, 0x41, 0x74, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, + 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x5f, 0x61, 0x74, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x65, + 0x6e, 0x64, 0x73, 0x5f, 0x61, 0x74, 0x1a, 0x36, 0x0a, 0x04, 0x54, 0x65, 0x78, 0x74, 0x12, 0x12, + 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x65, + 0x78, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x1a, 0xb8, + 0x01, 0x0a, 0x09, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x25, 0x0a, 0x08, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, + 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x52, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x22, + 0x0a, 0x05, 0x63, 0x61, 0x75, 0x73, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0c, 0x2e, + 0x41, 0x6c, 0x65, 0x72, 0x74, 0x2e, 0x43, 0x61, 0x75, 0x73, 0x65, 0x52, 0x05, 0x63, 0x61, 0x75, + 0x73, 0x65, 0x12, 0x25, 0x0a, 0x06, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x2e, 0x45, 0x66, 0x66, 0x65, 0x63, + 0x74, 0x52, 0x06, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x22, 0xd8, 0x01, 0x0a, 0x05, 0x43, 0x61, + 0x75, 0x73, 0x65, 0x12, 0x11, 0x0a, 0x0d, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x43, + 0x41, 0x55, 0x53, 0x45, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x4f, 0x54, 0x48, 0x45, 0x52, 0x5f, + 0x43, 0x41, 0x55, 0x53, 0x45, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x45, 0x43, 0x48, 0x4e, + 0x49, 0x43, 0x41, 0x4c, 0x5f, 0x50, 0x52, 0x4f, 0x42, 0x4c, 0x45, 0x4d, 0x10, 0x03, 0x12, 0x0a, + 0x0a, 0x06, 0x53, 0x54, 0x52, 0x49, 0x4b, 0x45, 0x10, 0x04, 0x12, 0x11, 0x0a, 0x0d, 0x44, 0x45, + 0x4d, 0x4f, 0x4e, 0x53, 0x54, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x05, 0x12, 0x0c, 0x0a, + 0x08, 0x41, 0x43, 0x43, 0x49, 0x44, 0x45, 0x4e, 0x54, 0x10, 0x06, 0x12, 0x0b, 0x0a, 0x07, 0x48, + 0x4f, 0x4c, 0x49, 0x44, 0x41, 0x59, 0x10, 0x07, 0x12, 0x0b, 0x0a, 0x07, 0x57, 0x45, 0x41, 0x54, + 0x48, 0x45, 0x52, 0x10, 0x08, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x41, 0x49, 0x4e, 0x54, 0x45, 0x4e, + 0x41, 0x4e, 0x43, 0x45, 0x10, 0x09, 0x12, 0x10, 0x0a, 0x0c, 0x43, 0x4f, 0x4e, 0x53, 0x54, 0x52, + 0x55, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x0a, 0x12, 0x13, 0x0a, 0x0f, 0x50, 0x4f, 0x4c, 0x49, + 0x43, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x49, 0x54, 0x59, 0x10, 0x0b, 0x12, 0x15, 0x0a, + 0x11, 0x4d, 0x45, 0x44, 0x49, 0x43, 0x41, 0x4c, 0x5f, 0x45, 0x4d, 0x45, 0x52, 0x47, 0x45, 0x4e, + 0x43, 0x59, 0x10, 0x0c, 0x22, 0xdd, 0x01, 0x0a, 0x06, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x12, + 0x12, 0x0a, 0x0e, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x45, 0x46, 0x46, 0x45, 0x43, + 0x54, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x4e, 0x4f, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, + 0x45, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x45, 0x44, 0x55, 0x43, 0x45, 0x44, 0x5f, 0x53, + 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x10, 0x02, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x49, 0x47, 0x4e, + 0x49, 0x46, 0x49, 0x43, 0x41, 0x4e, 0x54, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x53, 0x10, 0x03, + 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x54, 0x4f, 0x55, 0x52, 0x10, 0x04, 0x12, 0x16, 0x0a, 0x12, + 0x41, 0x44, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x41, 0x4c, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, + 0x43, 0x45, 0x10, 0x05, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x4f, 0x44, 0x49, 0x46, 0x49, 0x45, 0x44, + 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x10, 0x06, 0x12, 0x10, 0x0a, 0x0c, 0x4f, 0x54, + 0x48, 0x45, 0x52, 0x5f, 0x45, 0x46, 0x46, 0x45, 0x43, 0x54, 0x10, 0x07, 0x12, 0x0e, 0x0a, 0x0a, + 0x53, 0x54, 0x4f, 0x50, 0x5f, 0x4d, 0x4f, 0x56, 0x45, 0x44, 0x10, 0x09, 0x12, 0x0d, 0x0a, 0x09, + 0x4e, 0x4f, 0x5f, 0x45, 0x46, 0x46, 0x45, 0x43, 0x54, 0x10, 0x0a, 0x12, 0x17, 0x0a, 0x13, 0x41, + 0x43, 0x43, 0x45, 0x53, 0x53, 0x49, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x49, 0x53, 0x53, + 0x55, 0x45, 0x10, 0x0b, 0x42, 0x18, 0x0a, 0x16, 0x5f, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, + 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x22, 0xc3, + 0x02, 0x0a, 0x08, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x12, 0x2c, 0x0a, 0x09, 0x66, + 0x72, 0x6f, 0x6d, 0x5f, 0x73, 0x74, 0x6f, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, + 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, + 0x08, 0x66, 0x72, 0x6f, 0x6d, 0x53, 0x74, 0x6f, 0x70, 0x12, 0x28, 0x0a, 0x07, 0x74, 0x6f, 0x5f, + 0x73, 0x74, 0x6f, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x53, 0x74, 0x6f, + 0x70, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x06, 0x74, 0x6f, 0x53, + 0x74, 0x6f, 0x70, 0x12, 0x22, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x0e, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x54, 0x79, 0x70, + 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x2f, 0x0a, 0x11, 0x6d, 0x69, 0x6e, 0x5f, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x05, 0x48, 0x00, 0x52, 0x0f, 0x6d, 0x69, 0x6e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, + 0x72, 0x54, 0x69, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, 0x64, 0x69, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x48, 0x01, 0x52, 0x08, 0x64, 0x69, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x88, 0x01, 0x01, 0x22, 0x46, 0x0a, 0x04, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x52, 0x45, 0x43, 0x4f, 0x4d, 0x4d, 0x45, 0x4e, 0x44, 0x45, 0x44, + 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x54, 0x49, 0x4d, 0x45, 0x44, 0x10, 0x01, 0x12, 0x11, 0x0a, + 0x0d, 0x52, 0x45, 0x51, 0x55, 0x49, 0x52, 0x45, 0x53, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x10, 0x02, + 0x12, 0x0f, 0x0a, 0x0b, 0x4e, 0x4f, 0x5f, 0x50, 0x4f, 0x53, 0x53, 0x49, 0x42, 0x4c, 0x45, 0x10, + 0x03, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x6d, 0x69, 0x6e, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, + 0x65, 0x72, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x64, 0x69, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x32, 0xae, 0x0c, 0x0a, 0x06, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x12, + 0x3d, 0x0a, 0x0a, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x12, 0x2e, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x10, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x65, + 0x70, 0x6c, 0x79, 0x22, 0x09, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x03, 0x12, 0x01, 0x2f, 0x12, 0x47, + 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x13, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, + 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x10, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0a, 0x12, 0x08, 0x2f, + 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x45, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x53, 0x79, + 0x73, 0x74, 0x65, 0x6d, 0x12, 0x11, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x07, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, + 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x12, 0x14, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, + 0x6d, 0x73, 0x2f, 0x7b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x5f, + 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x12, 0x14, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, + 0x69, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, + 0x12, 0x1d, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2f, 0x7b, 0x73, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x12, + 0x5a, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x11, 0x2e, 0x47, + 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x07, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x22, 0x31, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2b, + 0x12, 0x29, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2f, 0x7b, 0x73, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x2f, + 0x7b, 0x61, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x53, 0x0a, 0x09, 0x4c, + 0x69, 0x73, 0x74, 0x53, 0x74, 0x6f, 0x70, 0x73, 0x12, 0x11, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, + 0x74, 0x6f, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x53, 0x74, 0x6f, 0x70, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x22, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2f, 0x7b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x73, 0x74, 0x6f, 0x70, 0x73, - 0x2f, 0x7b, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x57, 0x0a, 0x0a, 0x4c, 0x69, - 0x73, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x12, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, - 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x23, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, - 0x2f, 0x7b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x75, - 0x74, 0x65, 0x73, 0x12, 0x54, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, - 0x10, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x06, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x22, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x28, 0x12, 0x26, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2f, 0x7b, 0x73, 0x79, 0x73, - 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, - 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x65, 0x0a, 0x09, 0x4c, 0x69, 0x73, - 0x74, 0x54, 0x72, 0x69, 0x70, 0x73, 0x12, 0x11, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x69, - 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x54, 0x72, 0x69, 0x70, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x34, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x2e, 0x12, 0x2c, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2f, 0x7b, 0x73, 0x79, + 0x12, 0x4f, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x53, 0x74, 0x6f, 0x70, 0x12, 0x0f, 0x2e, 0x47, 0x65, + 0x74, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x05, 0x2e, 0x53, + 0x74, 0x6f, 0x70, 0x22, 0x2c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x12, 0x24, 0x2f, 0x73, 0x79, + 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2f, 0x7b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, + 0x7d, 0x2f, 0x73, 0x74, 0x6f, 0x70, 0x73, 0x2f, 0x7b, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x69, 0x64, + 0x7d, 0x12, 0x57, 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, + 0x12, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, + 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, + 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2f, 0x7b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, + 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x54, 0x0a, 0x08, 0x47, 0x65, + 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x10, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x06, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, + 0x22, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x28, 0x12, 0x26, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, + 0x6d, 0x73, 0x2f, 0x7b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, + 0x6f, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x7d, + 0x12, 0x65, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x69, 0x70, 0x73, 0x12, 0x11, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x69, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x0f, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x69, 0x70, 0x73, 0x52, 0x65, 0x70, 0x6c, + 0x79, 0x22, 0x34, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2e, 0x12, 0x2c, 0x2f, 0x73, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x73, 0x2f, 0x7b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x7d, 0x2f, + 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x64, + 0x7d, 0x2f, 0x74, 0x72, 0x69, 0x70, 0x73, 0x12, 0x61, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x54, 0x72, + 0x69, 0x70, 0x12, 0x0f, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x69, 0x70, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x05, 0x2e, 0x54, 0x72, 0x69, 0x70, 0x22, 0x3e, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x38, 0x12, 0x36, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2f, 0x7b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x74, 0x72, 0x69, 0x70, 0x73, - 0x12, 0x61, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x54, 0x72, 0x69, 0x70, 0x12, 0x0f, 0x2e, 0x47, 0x65, - 0x74, 0x54, 0x72, 0x69, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x05, 0x2e, 0x54, - 0x72, 0x69, 0x70, 0x22, 0x3e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x38, 0x12, 0x36, 0x2f, 0x73, 0x79, - 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2f, 0x7b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, - 0x7d, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, - 0x69, 0x64, 0x7d, 0x2f, 0x74, 0x72, 0x69, 0x70, 0x73, 0x2f, 0x7b, 0x74, 0x72, 0x69, 0x70, 0x5f, - 0x69, 0x64, 0x7d, 0x12, 0x57, 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x65, 0x72, 0x74, - 0x73, 0x12, 0x12, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x65, 0x72, - 0x74, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, - 0x1b, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2f, 0x7b, 0x73, 0x79, 0x73, 0x74, 0x65, - 0x6d, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x12, 0x54, 0x0a, 0x08, - 0x47, 0x65, 0x74, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x12, 0x10, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6c, - 0x65, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x06, 0x2e, 0x41, 0x6c, 0x65, - 0x72, 0x74, 0x22, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x28, 0x12, 0x26, 0x2f, 0x73, 0x79, 0x73, - 0x74, 0x65, 0x6d, 0x73, 0x2f, 0x7b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x7d, - 0x2f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x2f, 0x7b, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x5f, 0x69, - 0x64, 0x7d, 0x12, 0x63, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, - 0x65, 0x72, 0x73, 0x12, 0x15, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, - 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, - 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x12, 0x1e, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, - 0x73, 0x2f, 0x7b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x74, 0x72, - 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x12, 0x53, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x46, - 0x65, 0x65, 0x64, 0x73, 0x12, 0x11, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x65, 0x65, 0x64, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x65, - 0x65, 0x64, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, - 0x12, 0x1a, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2f, 0x7b, 0x73, 0x79, 0x73, 0x74, - 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x65, 0x65, 0x64, 0x73, 0x12, 0x4f, 0x0a, 0x07, - 0x47, 0x65, 0x74, 0x46, 0x65, 0x65, 0x64, 0x12, 0x0f, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x65, 0x65, - 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x05, 0x2e, 0x46, 0x65, 0x65, 0x64, 0x22, - 0x2c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x12, 0x24, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, + 0x2f, 0x7b, 0x74, 0x72, 0x69, 0x70, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x57, 0x0a, 0x0a, 0x4c, 0x69, + 0x73, 0x74, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x12, 0x12, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, + 0x6c, 0x65, 0x72, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x23, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, + 0x2f, 0x7b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x6c, 0x65, + 0x72, 0x74, 0x73, 0x12, 0x54, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x12, + 0x10, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x06, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x22, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x28, 0x12, 0x26, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2f, 0x7b, 0x73, 0x79, 0x73, + 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x2f, 0x7b, + 0x61, 0x6c, 0x65, 0x72, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x63, 0x0a, 0x0d, 0x4c, 0x69, 0x73, + 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x12, 0x15, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x13, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, + 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x12, 0x1e, + 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2f, 0x7b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, + 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x12, 0x53, + 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x65, 0x65, 0x64, 0x73, 0x12, 0x11, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x46, 0x65, 0x65, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x65, 0x65, 0x64, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, + 0x22, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2f, 0x7b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x65, - 0x65, 0x64, 0x73, 0x2f, 0x7b, 0x66, 0x65, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x7d, 0x42, 0x28, 0x5a, - 0x26, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6a, 0x61, 0x6d, 0x65, - 0x73, 0x70, 0x66, 0x65, 0x6e, 0x6e, 0x65, 0x6c, 0x6c, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, - 0x74, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x64, 0x73, 0x12, 0x4f, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x46, 0x65, 0x65, 0x64, 0x12, 0x0f, + 0x2e, 0x47, 0x65, 0x74, 0x46, 0x65, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x05, 0x2e, 0x46, 0x65, 0x65, 0x64, 0x22, 0x2c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x12, 0x24, + 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2f, 0x7b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, + 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x65, 0x65, 0x64, 0x73, 0x2f, 0x7b, 0x66, 0x65, 0x65, 0x64, + 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x5f, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x65, 0x68, 0x69, + 0x63, 0x6c, 0x65, 0x73, 0x12, 0x14, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x65, 0x68, 0x69, 0x63, + 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x56, 0x65, 0x68, 0x69, 0x63, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x25, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x12, 0x1d, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, + 0x2f, 0x7b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x76, 0x65, 0x68, + 0x69, 0x63, 0x6c, 0x65, 0x73, 0x12, 0x5e, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x56, 0x65, 0x68, 0x69, + 0x63, 0x6c, 0x65, 0x12, 0x12, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x65, 0x68, 0x69, 0x63, 0x6c, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x08, 0x2e, 0x56, 0x65, 0x68, 0x69, 0x63, 0x6c, + 0x65, 0x22, 0x32, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x12, 0x2a, 0x2f, 0x73, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x73, 0x2f, 0x7b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x7d, 0x2f, + 0x76, 0x65, 0x68, 0x69, 0x63, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x76, 0x65, 0x68, 0x69, 0x63, 0x6c, + 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x42, 0x28, 0x5a, 0x26, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x6a, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x66, 0x65, 0x6e, 0x6e, 0x65, 0x6c, + 0x6c, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -5435,192 +6167,211 @@ func file_api_public_proto_rawDescGZIP() []byte { return file_api_public_proto_rawDescData } -var file_api_public_proto_enumTypes = make([]protoimpl.EnumInfo, 8) -var file_api_public_proto_msgTypes = make([]protoimpl.MessageInfo, 53) +var file_api_public_proto_enumTypes = make([]protoimpl.EnumInfo, 12) +var file_api_public_proto_msgTypes = make([]protoimpl.MessageInfo, 56) var file_api_public_proto_goTypes = []interface{}{ (ListStopsRequest_SearchMode)(0), // 0: ListStopsRequest.SearchMode - (System_Status)(0), // 1: System.Status - (Stop_Type)(0), // 2: Stop.Type - (Route_ContinuousPolicy)(0), // 3: Route.ContinuousPolicy - (Route_Type)(0), // 4: Route.Type - (Alert_Cause)(0), // 5: Alert.Cause - (Alert_Effect)(0), // 6: Alert.Effect - (Transfer_Type)(0), // 7: Transfer.Type - (*EntrypointRequest)(nil), // 8: EntrypointRequest - (*EntrypointReply)(nil), // 9: EntrypointReply - (*ListSystemsRequest)(nil), // 10: ListSystemsRequest - (*ListSystemsReply)(nil), // 11: ListSystemsReply - (*GetSystemRequest)(nil), // 12: GetSystemRequest - (*ListAgenciesRequest)(nil), // 13: ListAgenciesRequest - (*ListAgenciesReply)(nil), // 14: ListAgenciesReply - (*GetAgencyRequest)(nil), // 15: GetAgencyRequest - (*ListStopsRequest)(nil), // 16: ListStopsRequest - (*ListStopsReply)(nil), // 17: ListStopsReply - (*GetStopRequest)(nil), // 18: GetStopRequest - (*ListRoutesRequest)(nil), // 19: ListRoutesRequest - (*ListRoutesReply)(nil), // 20: ListRoutesReply - (*GetRouteRequest)(nil), // 21: GetRouteRequest - (*ListTripsRequest)(nil), // 22: ListTripsRequest - (*ListTripsReply)(nil), // 23: ListTripsReply - (*ListAlertsRequest)(nil), // 24: ListAlertsRequest - (*ListAlertsReply)(nil), // 25: ListAlertsReply - (*GetAlertRequest)(nil), // 26: GetAlertRequest - (*GetTripRequest)(nil), // 27: GetTripRequest - (*ListFeedsRequest)(nil), // 28: ListFeedsRequest - (*ListFeedsReply)(nil), // 29: ListFeedsReply - (*GetFeedRequest)(nil), // 30: GetFeedRequest - (*ListTransfersRequest)(nil), // 31: ListTransfersRequest - (*ListTransfersReply)(nil), // 32: ListTransfersReply - (*System)(nil), // 33: System - (*Resource)(nil), // 34: Resource - (*ChildResources)(nil), // 35: ChildResources - (*Stop)(nil), // 36: Stop - (*StopTime)(nil), // 37: StopTime - (*Trip)(nil), // 38: Trip - (*Vehicle)(nil), // 39: Vehicle - (*Route)(nil), // 40: Route - (*Feed)(nil), // 41: Feed - (*Agency)(nil), // 42: Agency - (*Alert)(nil), // 43: Alert - (*Transfer)(nil), // 44: Transfer - (*EntrypointReply_TransiterDetails)(nil), // 45: EntrypointReply.TransiterDetails - (*EntrypointReply_TransiterDetails_Build)(nil), // 46: EntrypointReply.TransiterDetails.Build - (*System_Reference)(nil), // 47: System.Reference - (*Stop_ServiceMap)(nil), // 48: Stop.ServiceMap - (*Stop_HeadsignRule)(nil), // 49: Stop.HeadsignRule - (*Stop_Reference)(nil), // 50: Stop.Reference - (*StopTime_EstimatedTime)(nil), // 51: StopTime.EstimatedTime - (*Trip_Reference)(nil), // 52: Trip.Reference - (*Vehicle_Reference)(nil), // 53: Vehicle.Reference - (*Route_ServiceMap)(nil), // 54: Route.ServiceMap - (*Route_Reference)(nil), // 55: Route.Reference - (*Feed_Reference)(nil), // 56: Feed.Reference - (*Agency_Reference)(nil), // 57: Agency.Reference - (*Alert_ActivePeriod)(nil), // 58: Alert.ActivePeriod - (*Alert_Text)(nil), // 59: Alert.Text - (*Alert_Reference)(nil), // 60: Alert.Reference + (ListVehiclesRequest_SearchMode)(0), // 1: ListVehiclesRequest.SearchMode + (System_Status)(0), // 2: System.Status + (Stop_Type)(0), // 3: Stop.Type + (Vehicle_CurrentStatus)(0), // 4: Vehicle.CurrentStatus + (Vehicle_CongestionLevel)(0), // 5: Vehicle.CongestionLevel + (Vehicle_OccupancyStatus)(0), // 6: Vehicle.OccupancyStatus + (Route_ContinuousPolicy)(0), // 7: Route.ContinuousPolicy + (Route_Type)(0), // 8: Route.Type + (Alert_Cause)(0), // 9: Alert.Cause + (Alert_Effect)(0), // 10: Alert.Effect + (Transfer_Type)(0), // 11: Transfer.Type + (*EntrypointRequest)(nil), // 12: EntrypointRequest + (*EntrypointReply)(nil), // 13: EntrypointReply + (*ListSystemsRequest)(nil), // 14: ListSystemsRequest + (*ListSystemsReply)(nil), // 15: ListSystemsReply + (*GetSystemRequest)(nil), // 16: GetSystemRequest + (*ListAgenciesRequest)(nil), // 17: ListAgenciesRequest + (*ListAgenciesReply)(nil), // 18: ListAgenciesReply + (*GetAgencyRequest)(nil), // 19: GetAgencyRequest + (*ListStopsRequest)(nil), // 20: ListStopsRequest + (*ListStopsReply)(nil), // 21: ListStopsReply + (*GetStopRequest)(nil), // 22: GetStopRequest + (*ListRoutesRequest)(nil), // 23: ListRoutesRequest + (*ListRoutesReply)(nil), // 24: ListRoutesReply + (*GetRouteRequest)(nil), // 25: GetRouteRequest + (*ListTripsRequest)(nil), // 26: ListTripsRequest + (*ListTripsReply)(nil), // 27: ListTripsReply + (*ListAlertsRequest)(nil), // 28: ListAlertsRequest + (*ListAlertsReply)(nil), // 29: ListAlertsReply + (*GetAlertRequest)(nil), // 30: GetAlertRequest + (*GetTripRequest)(nil), // 31: GetTripRequest + (*ListFeedsRequest)(nil), // 32: ListFeedsRequest + (*ListFeedsReply)(nil), // 33: ListFeedsReply + (*GetFeedRequest)(nil), // 34: GetFeedRequest + (*ListTransfersRequest)(nil), // 35: ListTransfersRequest + (*ListTransfersReply)(nil), // 36: ListTransfersReply + (*ListVehiclesRequest)(nil), // 37: ListVehiclesRequest + (*ListVehiclesReply)(nil), // 38: ListVehiclesReply + (*GetVehicleRequest)(nil), // 39: GetVehicleRequest + (*System)(nil), // 40: System + (*Resource)(nil), // 41: Resource + (*ChildResources)(nil), // 42: ChildResources + (*Stop)(nil), // 43: Stop + (*StopTime)(nil), // 44: StopTime + (*Trip)(nil), // 45: Trip + (*Vehicle)(nil), // 46: Vehicle + (*Route)(nil), // 47: Route + (*Feed)(nil), // 48: Feed + (*Agency)(nil), // 49: Agency + (*Alert)(nil), // 50: Alert + (*Transfer)(nil), // 51: Transfer + (*EntrypointReply_TransiterDetails)(nil), // 52: EntrypointReply.TransiterDetails + (*EntrypointReply_TransiterDetails_Build)(nil), // 53: EntrypointReply.TransiterDetails.Build + (*System_Reference)(nil), // 54: System.Reference + (*Stop_ServiceMap)(nil), // 55: Stop.ServiceMap + (*Stop_HeadsignRule)(nil), // 56: Stop.HeadsignRule + (*Stop_Reference)(nil), // 57: Stop.Reference + (*StopTime_EstimatedTime)(nil), // 58: StopTime.EstimatedTime + (*Trip_Reference)(nil), // 59: Trip.Reference + (*Vehicle_Reference)(nil), // 60: Vehicle.Reference + (*Route_ServiceMap)(nil), // 61: Route.ServiceMap + (*Route_Reference)(nil), // 62: Route.Reference + (*Feed_Reference)(nil), // 63: Feed.Reference + (*Agency_Reference)(nil), // 64: Agency.Reference + (*Alert_ActivePeriod)(nil), // 65: Alert.ActivePeriod + (*Alert_Text)(nil), // 66: Alert.Text + (*Alert_Reference)(nil), // 67: Alert.Reference } var file_api_public_proto_depIdxs = []int32{ - 45, // 0: EntrypointReply.transiter:type_name -> EntrypointReply.TransiterDetails - 35, // 1: EntrypointReply.systems:type_name -> ChildResources - 33, // 2: ListSystemsReply.systems:type_name -> System - 42, // 3: ListAgenciesReply.agencies:type_name -> Agency - 0, // 4: ListStopsRequest.search_mode:type_name -> ListStopsRequest.SearchMode - 36, // 5: ListStopsReply.stops:type_name -> Stop - 40, // 6: ListRoutesReply.routes:type_name -> Route - 38, // 7: ListTripsReply.trips:type_name -> Trip - 43, // 8: ListAlertsReply.alerts:type_name -> Alert - 41, // 9: ListFeedsReply.feeds:type_name -> Feed - 44, // 10: ListTransfersReply.transfers:type_name -> Transfer - 34, // 11: System.resource:type_name -> Resource - 1, // 12: System.status:type_name -> System.Status - 35, // 13: System.agencies:type_name -> ChildResources - 35, // 14: System.feeds:type_name -> ChildResources - 35, // 15: System.routes:type_name -> ChildResources - 35, // 16: System.stops:type_name -> ChildResources - 35, // 17: System.transfers:type_name -> ChildResources - 34, // 18: Stop.resource:type_name -> Resource - 47, // 19: Stop.system:type_name -> System.Reference - 2, // 20: Stop.type:type_name -> Stop.Type - 50, // 21: Stop.parent_stop:type_name -> Stop.Reference - 50, // 22: Stop.child_stops:type_name -> Stop.Reference - 48, // 23: Stop.service_maps:type_name -> Stop.ServiceMap - 60, // 24: Stop.alerts:type_name -> Alert.Reference - 37, // 25: Stop.stop_times:type_name -> StopTime - 44, // 26: Stop.transfers:type_name -> Transfer - 49, // 27: Stop.headsign_rules:type_name -> Stop.HeadsignRule - 50, // 28: StopTime.stop:type_name -> Stop.Reference - 52, // 29: StopTime.trip:type_name -> Trip.Reference - 51, // 30: StopTime.arrival:type_name -> StopTime.EstimatedTime - 51, // 31: StopTime.departure:type_name -> StopTime.EstimatedTime - 34, // 32: Trip.resource:type_name -> Resource - 55, // 33: Trip.route:type_name -> Route.Reference - 53, // 34: Trip.vehicle:type_name -> Vehicle.Reference - 37, // 35: Trip.stop_times:type_name -> StopTime - 34, // 36: Route.resource:type_name -> Resource - 47, // 37: Route.system:type_name -> System.Reference - 3, // 38: Route.continuous_pickup:type_name -> Route.ContinuousPolicy - 3, // 39: Route.continuous_drop_off:type_name -> Route.ContinuousPolicy - 4, // 40: Route.type:type_name -> Route.Type - 57, // 41: Route.agency:type_name -> Agency.Reference - 60, // 42: Route.alerts:type_name -> Alert.Reference - 54, // 43: Route.service_maps:type_name -> Route.ServiceMap - 34, // 44: Feed.resource:type_name -> Resource - 47, // 45: Feed.system:type_name -> System.Reference - 34, // 46: Agency.resource:type_name -> Resource - 47, // 47: Agency.system:type_name -> System.Reference - 55, // 48: Agency.routes:type_name -> Route.Reference - 60, // 49: Agency.alerts:type_name -> Alert.Reference - 34, // 50: Alert.resource:type_name -> Resource - 47, // 51: Alert.system:type_name -> System.Reference - 5, // 52: Alert.cause:type_name -> Alert.Cause - 6, // 53: Alert.effect:type_name -> Alert.Effect - 58, // 54: Alert.current_active_period:type_name -> Alert.ActivePeriod - 58, // 55: Alert.all_active_periods:type_name -> Alert.ActivePeriod - 59, // 56: Alert.header:type_name -> Alert.Text - 59, // 57: Alert.description:type_name -> Alert.Text - 59, // 58: Alert.url:type_name -> Alert.Text - 50, // 59: Transfer.from_stop:type_name -> Stop.Reference - 50, // 60: Transfer.to_stop:type_name -> Stop.Reference - 7, // 61: Transfer.type:type_name -> Transfer.Type - 46, // 62: EntrypointReply.TransiterDetails.build:type_name -> EntrypointReply.TransiterDetails.Build - 34, // 63: System.Reference.resource:type_name -> Resource - 55, // 64: Stop.ServiceMap.routes:type_name -> Route.Reference - 50, // 65: Stop.HeadsignRule.stop:type_name -> Stop.Reference - 34, // 66: Stop.Reference.resource:type_name -> Resource - 47, // 67: Stop.Reference.system:type_name -> System.Reference - 34, // 68: Trip.Reference.resource:type_name -> Resource - 55, // 69: Trip.Reference.route:type_name -> Route.Reference - 50, // 70: Trip.Reference.destination:type_name -> Stop.Reference - 53, // 71: Trip.Reference.vehicle:type_name -> Vehicle.Reference - 50, // 72: Route.ServiceMap.stops:type_name -> Stop.Reference - 34, // 73: Route.Reference.resource:type_name -> Resource - 47, // 74: Route.Reference.system:type_name -> System.Reference - 34, // 75: Feed.Reference.resource:type_name -> Resource - 47, // 76: Feed.Reference.system:type_name -> System.Reference - 34, // 77: Agency.Reference.resource:type_name -> Resource - 47, // 78: Agency.Reference.system:type_name -> System.Reference - 34, // 79: Alert.Reference.resource:type_name -> Resource - 47, // 80: Alert.Reference.system:type_name -> System.Reference - 5, // 81: Alert.Reference.cause:type_name -> Alert.Cause - 6, // 82: Alert.Reference.effect:type_name -> Alert.Effect - 8, // 83: Public.Entrypoint:input_type -> EntrypointRequest - 10, // 84: Public.ListSystems:input_type -> ListSystemsRequest - 12, // 85: Public.GetSystem:input_type -> GetSystemRequest - 13, // 86: Public.ListAgencies:input_type -> ListAgenciesRequest - 15, // 87: Public.GetAgency:input_type -> GetAgencyRequest - 16, // 88: Public.ListStops:input_type -> ListStopsRequest - 18, // 89: Public.GetStop:input_type -> GetStopRequest - 19, // 90: Public.ListRoutes:input_type -> ListRoutesRequest - 21, // 91: Public.GetRoute:input_type -> GetRouteRequest - 22, // 92: Public.ListTrips:input_type -> ListTripsRequest - 27, // 93: Public.GetTrip:input_type -> GetTripRequest - 24, // 94: Public.ListAlerts:input_type -> ListAlertsRequest - 26, // 95: Public.GetAlert:input_type -> GetAlertRequest - 31, // 96: Public.ListTransfers:input_type -> ListTransfersRequest - 28, // 97: Public.ListFeeds:input_type -> ListFeedsRequest - 30, // 98: Public.GetFeed:input_type -> GetFeedRequest - 9, // 99: Public.Entrypoint:output_type -> EntrypointReply - 11, // 100: Public.ListSystems:output_type -> ListSystemsReply - 33, // 101: Public.GetSystem:output_type -> System - 14, // 102: Public.ListAgencies:output_type -> ListAgenciesReply - 42, // 103: Public.GetAgency:output_type -> Agency - 17, // 104: Public.ListStops:output_type -> ListStopsReply - 36, // 105: Public.GetStop:output_type -> Stop - 20, // 106: Public.ListRoutes:output_type -> ListRoutesReply - 40, // 107: Public.GetRoute:output_type -> Route - 23, // 108: Public.ListTrips:output_type -> ListTripsReply - 38, // 109: Public.GetTrip:output_type -> Trip - 25, // 110: Public.ListAlerts:output_type -> ListAlertsReply - 43, // 111: Public.GetAlert:output_type -> Alert - 32, // 112: Public.ListTransfers:output_type -> ListTransfersReply - 29, // 113: Public.ListFeeds:output_type -> ListFeedsReply - 41, // 114: Public.GetFeed:output_type -> Feed - 99, // [99:115] is the sub-list for method output_type - 83, // [83:99] is the sub-list for method input_type - 83, // [83:83] is the sub-list for extension type_name - 83, // [83:83] is the sub-list for extension extendee - 0, // [0:83] is the sub-list for field type_name + 52, // 0: EntrypointReply.transiter:type_name -> EntrypointReply.TransiterDetails + 42, // 1: EntrypointReply.systems:type_name -> ChildResources + 40, // 2: ListSystemsReply.systems:type_name -> System + 49, // 3: ListAgenciesReply.agencies:type_name -> Agency + 0, // 4: ListStopsRequest.search_mode:type_name -> ListStopsRequest.SearchMode + 43, // 5: ListStopsReply.stops:type_name -> Stop + 47, // 6: ListRoutesReply.routes:type_name -> Route + 45, // 7: ListTripsReply.trips:type_name -> Trip + 50, // 8: ListAlertsReply.alerts:type_name -> Alert + 48, // 9: ListFeedsReply.feeds:type_name -> Feed + 51, // 10: ListTransfersReply.transfers:type_name -> Transfer + 1, // 11: ListVehiclesRequest.search_mode:type_name -> ListVehiclesRequest.SearchMode + 46, // 12: ListVehiclesReply.vehicles:type_name -> Vehicle + 41, // 13: System.resource:type_name -> Resource + 2, // 14: System.status:type_name -> System.Status + 42, // 15: System.agencies:type_name -> ChildResources + 42, // 16: System.feeds:type_name -> ChildResources + 42, // 17: System.routes:type_name -> ChildResources + 42, // 18: System.stops:type_name -> ChildResources + 42, // 19: System.transfers:type_name -> ChildResources + 41, // 20: Stop.resource:type_name -> Resource + 54, // 21: Stop.system:type_name -> System.Reference + 3, // 22: Stop.type:type_name -> Stop.Type + 57, // 23: Stop.parent_stop:type_name -> Stop.Reference + 57, // 24: Stop.child_stops:type_name -> Stop.Reference + 55, // 25: Stop.service_maps:type_name -> Stop.ServiceMap + 67, // 26: Stop.alerts:type_name -> Alert.Reference + 44, // 27: Stop.stop_times:type_name -> StopTime + 51, // 28: Stop.transfers:type_name -> Transfer + 56, // 29: Stop.headsign_rules:type_name -> Stop.HeadsignRule + 57, // 30: StopTime.stop:type_name -> Stop.Reference + 59, // 31: StopTime.trip:type_name -> Trip.Reference + 58, // 32: StopTime.arrival:type_name -> StopTime.EstimatedTime + 58, // 33: StopTime.departure:type_name -> StopTime.EstimatedTime + 41, // 34: Trip.resource:type_name -> Resource + 62, // 35: Trip.route:type_name -> Route.Reference + 60, // 36: Trip.vehicle:type_name -> Vehicle.Reference + 44, // 37: Trip.stop_times:type_name -> StopTime + 59, // 38: Vehicle.trip:type_name -> Trip.Reference + 57, // 39: Vehicle.stop:type_name -> Stop.Reference + 4, // 40: Vehicle.current_status:type_name -> Vehicle.CurrentStatus + 5, // 41: Vehicle.congestion_level:type_name -> Vehicle.CongestionLevel + 6, // 42: Vehicle.occupancy_status:type_name -> Vehicle.OccupancyStatus + 41, // 43: Route.resource:type_name -> Resource + 54, // 44: Route.system:type_name -> System.Reference + 7, // 45: Route.continuous_pickup:type_name -> Route.ContinuousPolicy + 7, // 46: Route.continuous_drop_off:type_name -> Route.ContinuousPolicy + 8, // 47: Route.type:type_name -> Route.Type + 64, // 48: Route.agency:type_name -> Agency.Reference + 67, // 49: Route.alerts:type_name -> Alert.Reference + 61, // 50: Route.service_maps:type_name -> Route.ServiceMap + 41, // 51: Feed.resource:type_name -> Resource + 54, // 52: Feed.system:type_name -> System.Reference + 41, // 53: Agency.resource:type_name -> Resource + 54, // 54: Agency.system:type_name -> System.Reference + 62, // 55: Agency.routes:type_name -> Route.Reference + 67, // 56: Agency.alerts:type_name -> Alert.Reference + 41, // 57: Alert.resource:type_name -> Resource + 54, // 58: Alert.system:type_name -> System.Reference + 9, // 59: Alert.cause:type_name -> Alert.Cause + 10, // 60: Alert.effect:type_name -> Alert.Effect + 65, // 61: Alert.current_active_period:type_name -> Alert.ActivePeriod + 65, // 62: Alert.all_active_periods:type_name -> Alert.ActivePeriod + 66, // 63: Alert.header:type_name -> Alert.Text + 66, // 64: Alert.description:type_name -> Alert.Text + 66, // 65: Alert.url:type_name -> Alert.Text + 57, // 66: Transfer.from_stop:type_name -> Stop.Reference + 57, // 67: Transfer.to_stop:type_name -> Stop.Reference + 11, // 68: Transfer.type:type_name -> Transfer.Type + 53, // 69: EntrypointReply.TransiterDetails.build:type_name -> EntrypointReply.TransiterDetails.Build + 41, // 70: System.Reference.resource:type_name -> Resource + 62, // 71: Stop.ServiceMap.routes:type_name -> Route.Reference + 57, // 72: Stop.HeadsignRule.stop:type_name -> Stop.Reference + 41, // 73: Stop.Reference.resource:type_name -> Resource + 54, // 74: Stop.Reference.system:type_name -> System.Reference + 41, // 75: Trip.Reference.resource:type_name -> Resource + 62, // 76: Trip.Reference.route:type_name -> Route.Reference + 57, // 77: Trip.Reference.destination:type_name -> Stop.Reference + 60, // 78: Trip.Reference.vehicle:type_name -> Vehicle.Reference + 41, // 79: Vehicle.Reference.resource:type_name -> Resource + 57, // 80: Route.ServiceMap.stops:type_name -> Stop.Reference + 41, // 81: Route.Reference.resource:type_name -> Resource + 54, // 82: Route.Reference.system:type_name -> System.Reference + 41, // 83: Feed.Reference.resource:type_name -> Resource + 54, // 84: Feed.Reference.system:type_name -> System.Reference + 41, // 85: Agency.Reference.resource:type_name -> Resource + 54, // 86: Agency.Reference.system:type_name -> System.Reference + 41, // 87: Alert.Reference.resource:type_name -> Resource + 54, // 88: Alert.Reference.system:type_name -> System.Reference + 9, // 89: Alert.Reference.cause:type_name -> Alert.Cause + 10, // 90: Alert.Reference.effect:type_name -> Alert.Effect + 12, // 91: Public.Entrypoint:input_type -> EntrypointRequest + 14, // 92: Public.ListSystems:input_type -> ListSystemsRequest + 16, // 93: Public.GetSystem:input_type -> GetSystemRequest + 17, // 94: Public.ListAgencies:input_type -> ListAgenciesRequest + 19, // 95: Public.GetAgency:input_type -> GetAgencyRequest + 20, // 96: Public.ListStops:input_type -> ListStopsRequest + 22, // 97: Public.GetStop:input_type -> GetStopRequest + 23, // 98: Public.ListRoutes:input_type -> ListRoutesRequest + 25, // 99: Public.GetRoute:input_type -> GetRouteRequest + 26, // 100: Public.ListTrips:input_type -> ListTripsRequest + 31, // 101: Public.GetTrip:input_type -> GetTripRequest + 28, // 102: Public.ListAlerts:input_type -> ListAlertsRequest + 30, // 103: Public.GetAlert:input_type -> GetAlertRequest + 35, // 104: Public.ListTransfers:input_type -> ListTransfersRequest + 32, // 105: Public.ListFeeds:input_type -> ListFeedsRequest + 34, // 106: Public.GetFeed:input_type -> GetFeedRequest + 37, // 107: Public.ListVehicles:input_type -> ListVehiclesRequest + 39, // 108: Public.GetVehicle:input_type -> GetVehicleRequest + 13, // 109: Public.Entrypoint:output_type -> EntrypointReply + 15, // 110: Public.ListSystems:output_type -> ListSystemsReply + 40, // 111: Public.GetSystem:output_type -> System + 18, // 112: Public.ListAgencies:output_type -> ListAgenciesReply + 49, // 113: Public.GetAgency:output_type -> Agency + 21, // 114: Public.ListStops:output_type -> ListStopsReply + 43, // 115: Public.GetStop:output_type -> Stop + 24, // 116: Public.ListRoutes:output_type -> ListRoutesReply + 47, // 117: Public.GetRoute:output_type -> Route + 27, // 118: Public.ListTrips:output_type -> ListTripsReply + 45, // 119: Public.GetTrip:output_type -> Trip + 29, // 120: Public.ListAlerts:output_type -> ListAlertsReply + 50, // 121: Public.GetAlert:output_type -> Alert + 36, // 122: Public.ListTransfers:output_type -> ListTransfersReply + 33, // 123: Public.ListFeeds:output_type -> ListFeedsReply + 48, // 124: Public.GetFeed:output_type -> Feed + 38, // 125: Public.ListVehicles:output_type -> ListVehiclesReply + 46, // 126: Public.GetVehicle:output_type -> Vehicle + 109, // [109:127] is the sub-list for method output_type + 91, // [91:109] is the sub-list for method input_type + 91, // [91:91] is the sub-list for extension type_name + 91, // [91:91] is the sub-list for extension extendee + 0, // [0:91] is the sub-list for field type_name } func init() { file_api_public_proto_init() } @@ -5930,7 +6681,7 @@ func file_api_public_proto_init() { } } file_api_public_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*System); i { + switch v := v.(*ListVehiclesRequest); i { case 0: return &v.state case 1: @@ -5942,7 +6693,7 @@ func file_api_public_proto_init() { } } file_api_public_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Resource); i { + switch v := v.(*ListVehiclesReply); i { case 0: return &v.state case 1: @@ -5954,7 +6705,7 @@ func file_api_public_proto_init() { } } file_api_public_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ChildResources); i { + switch v := v.(*GetVehicleRequest); i { case 0: return &v.state case 1: @@ -5966,7 +6717,7 @@ func file_api_public_proto_init() { } } file_api_public_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Stop); i { + switch v := v.(*System); i { case 0: return &v.state case 1: @@ -5978,7 +6729,7 @@ func file_api_public_proto_init() { } } file_api_public_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*StopTime); i { + switch v := v.(*Resource); i { case 0: return &v.state case 1: @@ -5990,7 +6741,7 @@ func file_api_public_proto_init() { } } file_api_public_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Trip); i { + switch v := v.(*ChildResources); i { case 0: return &v.state case 1: @@ -6002,7 +6753,7 @@ func file_api_public_proto_init() { } } file_api_public_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Vehicle); i { + switch v := v.(*Stop); i { case 0: return &v.state case 1: @@ -6014,7 +6765,7 @@ func file_api_public_proto_init() { } } file_api_public_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Route); i { + switch v := v.(*StopTime); i { case 0: return &v.state case 1: @@ -6026,7 +6777,7 @@ func file_api_public_proto_init() { } } file_api_public_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Feed); i { + switch v := v.(*Trip); i { case 0: return &v.state case 1: @@ -6038,7 +6789,7 @@ func file_api_public_proto_init() { } } file_api_public_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Agency); i { + switch v := v.(*Vehicle); i { case 0: return &v.state case 1: @@ -6050,7 +6801,7 @@ func file_api_public_proto_init() { } } file_api_public_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Alert); i { + switch v := v.(*Route); i { case 0: return &v.state case 1: @@ -6062,7 +6813,7 @@ func file_api_public_proto_init() { } } file_api_public_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Transfer); i { + switch v := v.(*Feed); i { case 0: return &v.state case 1: @@ -6074,7 +6825,7 @@ func file_api_public_proto_init() { } } file_api_public_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*EntrypointReply_TransiterDetails); i { + switch v := v.(*Agency); i { case 0: return &v.state case 1: @@ -6086,7 +6837,7 @@ func file_api_public_proto_init() { } } file_api_public_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*EntrypointReply_TransiterDetails_Build); i { + switch v := v.(*Alert); i { case 0: return &v.state case 1: @@ -6098,7 +6849,7 @@ func file_api_public_proto_init() { } } file_api_public_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*System_Reference); i { + switch v := v.(*Transfer); i { case 0: return &v.state case 1: @@ -6110,7 +6861,7 @@ func file_api_public_proto_init() { } } file_api_public_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Stop_ServiceMap); i { + switch v := v.(*EntrypointReply_TransiterDetails); i { case 0: return &v.state case 1: @@ -6122,7 +6873,7 @@ func file_api_public_proto_init() { } } file_api_public_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Stop_HeadsignRule); i { + switch v := v.(*EntrypointReply_TransiterDetails_Build); i { case 0: return &v.state case 1: @@ -6134,7 +6885,7 @@ func file_api_public_proto_init() { } } file_api_public_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Stop_Reference); i { + switch v := v.(*System_Reference); i { case 0: return &v.state case 1: @@ -6146,7 +6897,7 @@ func file_api_public_proto_init() { } } file_api_public_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*StopTime_EstimatedTime); i { + switch v := v.(*Stop_ServiceMap); i { case 0: return &v.state case 1: @@ -6158,7 +6909,7 @@ func file_api_public_proto_init() { } } file_api_public_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Trip_Reference); i { + switch v := v.(*Stop_HeadsignRule); i { case 0: return &v.state case 1: @@ -6170,7 +6921,7 @@ func file_api_public_proto_init() { } } file_api_public_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Vehicle_Reference); i { + switch v := v.(*Stop_Reference); i { case 0: return &v.state case 1: @@ -6182,7 +6933,7 @@ func file_api_public_proto_init() { } } file_api_public_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Route_ServiceMap); i { + switch v := v.(*StopTime_EstimatedTime); i { case 0: return &v.state case 1: @@ -6194,7 +6945,7 @@ func file_api_public_proto_init() { } } file_api_public_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Route_Reference); i { + switch v := v.(*Trip_Reference); i { case 0: return &v.state case 1: @@ -6206,7 +6957,7 @@ func file_api_public_proto_init() { } } file_api_public_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Feed_Reference); i { + switch v := v.(*Vehicle_Reference); i { case 0: return &v.state case 1: @@ -6218,7 +6969,7 @@ func file_api_public_proto_init() { } } file_api_public_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Agency_Reference); i { + switch v := v.(*Route_ServiceMap); i { case 0: return &v.state case 1: @@ -6230,7 +6981,7 @@ func file_api_public_proto_init() { } } file_api_public_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Alert_ActivePeriod); i { + switch v := v.(*Route_Reference); i { case 0: return &v.state case 1: @@ -6242,7 +6993,7 @@ func file_api_public_proto_init() { } } file_api_public_proto_msgTypes[51].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Alert_Text); i { + switch v := v.(*Feed_Reference); i { case 0: return &v.state case 1: @@ -6254,6 +7005,42 @@ func file_api_public_proto_init() { } } file_api_public_proto_msgTypes[52].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Agency_Reference); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_public_proto_msgTypes[53].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Alert_ActivePeriod); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_public_proto_msgTypes[54].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Alert_Text); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_public_proto_msgTypes[55].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Alert_Reference); i { case 0: return &v.state @@ -6268,29 +7055,32 @@ func file_api_public_proto_init() { } file_api_public_proto_msgTypes[8].OneofWrappers = []interface{}{} file_api_public_proto_msgTypes[9].OneofWrappers = []interface{}{} + file_api_public_proto_msgTypes[25].OneofWrappers = []interface{}{} file_api_public_proto_msgTypes[26].OneofWrappers = []interface{}{} - file_api_public_proto_msgTypes[27].OneofWrappers = []interface{}{} - file_api_public_proto_msgTypes[28].OneofWrappers = []interface{}{} file_api_public_proto_msgTypes[29].OneofWrappers = []interface{}{} file_api_public_proto_msgTypes[30].OneofWrappers = []interface{}{} + file_api_public_proto_msgTypes[31].OneofWrappers = []interface{}{} file_api_public_proto_msgTypes[32].OneofWrappers = []interface{}{} file_api_public_proto_msgTypes[33].OneofWrappers = []interface{}{} file_api_public_proto_msgTypes[34].OneofWrappers = []interface{}{} file_api_public_proto_msgTypes[35].OneofWrappers = []interface{}{} file_api_public_proto_msgTypes[36].OneofWrappers = []interface{}{} file_api_public_proto_msgTypes[37].OneofWrappers = []interface{}{} - file_api_public_proto_msgTypes[41].OneofWrappers = []interface{}{} - file_api_public_proto_msgTypes[42].OneofWrappers = []interface{}{} - file_api_public_proto_msgTypes[43].OneofWrappers = []interface{}{} + file_api_public_proto_msgTypes[38].OneofWrappers = []interface{}{} + file_api_public_proto_msgTypes[39].OneofWrappers = []interface{}{} + file_api_public_proto_msgTypes[40].OneofWrappers = []interface{}{} file_api_public_proto_msgTypes[44].OneofWrappers = []interface{}{} - file_api_public_proto_msgTypes[50].OneofWrappers = []interface{}{} + file_api_public_proto_msgTypes[45].OneofWrappers = []interface{}{} + file_api_public_proto_msgTypes[46].OneofWrappers = []interface{}{} + file_api_public_proto_msgTypes[47].OneofWrappers = []interface{}{} + file_api_public_proto_msgTypes[53].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_api_public_proto_rawDesc, - NumEnums: 8, - NumMessages: 53, + NumEnums: 12, + NumMessages: 56, NumExtensions: 0, NumServices: 1, }, diff --git a/internal/gen/api/public.pb.gw.go b/internal/gen/api/public.pb.gw.go index 0cc7e9cd..b8386df0 100644 --- a/internal/gen/api/public.pb.gw.go +++ b/internal/gen/api/public.pb.gw.go @@ -1045,6 +1045,148 @@ func local_request_Public_GetFeed_0(ctx context.Context, marshaler runtime.Marsh } +var ( + filter_Public_ListVehicles_0 = &utilities.DoubleArray{Encoding: map[string]int{"system_id": 0, "systemId": 1}, Base: []int{1, 1, 2, 0, 0}, Check: []int{0, 1, 1, 2, 3}} +) + +func request_Public_ListVehicles_0(ctx context.Context, marshaler runtime.Marshaler, client PublicClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListVehiclesRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["system_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "system_id") + } + + protoReq.SystemId, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "system_id", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Public_ListVehicles_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ListVehicles(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Public_ListVehicles_0(ctx context.Context, marshaler runtime.Marshaler, server PublicServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListVehiclesRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["system_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "system_id") + } + + protoReq.SystemId, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "system_id", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Public_ListVehicles_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ListVehicles(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Public_GetVehicle_0(ctx context.Context, marshaler runtime.Marshaler, client PublicClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetVehicleRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["system_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "system_id") + } + + protoReq.SystemId, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "system_id", err) + } + + val, ok = pathParams["vehicle_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "vehicle_id") + } + + protoReq.VehicleId, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "vehicle_id", err) + } + + msg, err := client.GetVehicle(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Public_GetVehicle_0(ctx context.Context, marshaler runtime.Marshaler, server PublicServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetVehicleRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["system_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "system_id") + } + + protoReq.SystemId, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "system_id", err) + } + + val, ok = pathParams["vehicle_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "vehicle_id") + } + + protoReq.VehicleId, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "vehicle_id", err) + } + + msg, err := server.GetVehicle(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterPublicHandlerServer registers the http handlers for service Public to "mux". // UnaryRPC :call PublicServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -1451,6 +1593,56 @@ func RegisterPublicHandlerServer(ctx context.Context, mux *runtime.ServeMux, ser }) + mux.Handle("GET", pattern_Public_ListVehicles_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/.Public/ListVehicles", runtime.WithHTTPPathPattern("/systems/{system_id}/vehicles")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Public_ListVehicles_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Public_ListVehicles_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Public_GetVehicle_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/.Public/GetVehicle", runtime.WithHTTPPathPattern("/systems/{system_id}/vehicles/{vehicle_id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Public_GetVehicle_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Public_GetVehicle_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -1844,6 +2036,50 @@ func RegisterPublicHandlerClient(ctx context.Context, mux *runtime.ServeMux, cli }) + mux.Handle("GET", pattern_Public_ListVehicles_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/.Public/ListVehicles", runtime.WithHTTPPathPattern("/systems/{system_id}/vehicles")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Public_ListVehicles_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Public_ListVehicles_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Public_GetVehicle_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/.Public/GetVehicle", runtime.WithHTTPPathPattern("/systems/{system_id}/vehicles/{vehicle_id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Public_GetVehicle_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Public_GetVehicle_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -1879,6 +2115,10 @@ var ( pattern_Public_ListFeeds_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1, 2, 2}, []string{"systems", "system_id", "feeds"}, "")) pattern_Public_GetFeed_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"systems", "system_id", "feeds", "feed_id"}, "")) + + pattern_Public_ListVehicles_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1, 2, 2}, []string{"systems", "system_id", "vehicles"}, "")) + + pattern_Public_GetVehicle_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"systems", "system_id", "vehicles", "vehicle_id"}, "")) ) var ( @@ -1913,4 +2153,8 @@ var ( forward_Public_ListFeeds_0 = runtime.ForwardResponseMessage forward_Public_GetFeed_0 = runtime.ForwardResponseMessage + + forward_Public_ListVehicles_0 = runtime.ForwardResponseMessage + + forward_Public_GetVehicle_0 = runtime.ForwardResponseMessage ) diff --git a/internal/gen/api/public_grpc.pb.go b/internal/gen/api/public_grpc.pb.go index 2a5a351e..8c102751 100644 --- a/internal/gen/api/public_grpc.pb.go +++ b/internal/gen/api/public_grpc.pb.go @@ -121,6 +121,18 @@ type PublicClient interface { // // Get a feed in a system by its ID. GetFeed(ctx context.Context, in *GetFeedRequest, opts ...grpc.CallOption) (*Feed, error) + // List vehicles + // + // `GET /systems//vehicles` + // + // List all feeds for a system. + ListVehicles(ctx context.Context, in *ListVehiclesRequest, opts ...grpc.CallOption) (*ListVehiclesReply, error) + // Get vehicle + // + // `GET /systems//vehicles/` + // + // Get a vehicle in a system by its ID. + GetVehicle(ctx context.Context, in *GetVehicleRequest, opts ...grpc.CallOption) (*Vehicle, error) } type publicClient struct { @@ -275,6 +287,24 @@ func (c *publicClient) GetFeed(ctx context.Context, in *GetFeedRequest, opts ... return out, nil } +func (c *publicClient) ListVehicles(ctx context.Context, in *ListVehiclesRequest, opts ...grpc.CallOption) (*ListVehiclesReply, error) { + out := new(ListVehiclesReply) + err := c.cc.Invoke(ctx, "/Public/ListVehicles", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *publicClient) GetVehicle(ctx context.Context, in *GetVehicleRequest, opts ...grpc.CallOption) (*Vehicle, error) { + out := new(Vehicle) + err := c.cc.Invoke(ctx, "/Public/GetVehicle", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // PublicServer is the server API for Public service. // All implementations should embed UnimplementedPublicServer // for forward compatibility @@ -382,6 +412,18 @@ type PublicServer interface { // // Get a feed in a system by its ID. GetFeed(context.Context, *GetFeedRequest) (*Feed, error) + // List vehicles + // + // `GET /systems//vehicles` + // + // List all feeds for a system. + ListVehicles(context.Context, *ListVehiclesRequest) (*ListVehiclesReply, error) + // Get vehicle + // + // `GET /systems//vehicles/` + // + // Get a vehicle in a system by its ID. + GetVehicle(context.Context, *GetVehicleRequest) (*Vehicle, error) } // UnimplementedPublicServer should be embedded to have forward compatible implementations. @@ -436,6 +478,12 @@ func (UnimplementedPublicServer) ListFeeds(context.Context, *ListFeedsRequest) ( func (UnimplementedPublicServer) GetFeed(context.Context, *GetFeedRequest) (*Feed, error) { return nil, status.Errorf(codes.Unimplemented, "method GetFeed not implemented") } +func (UnimplementedPublicServer) ListVehicles(context.Context, *ListVehiclesRequest) (*ListVehiclesReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListVehicles not implemented") +} +func (UnimplementedPublicServer) GetVehicle(context.Context, *GetVehicleRequest) (*Vehicle, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetVehicle not implemented") +} // UnsafePublicServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to PublicServer will @@ -736,6 +784,42 @@ func _Public_GetFeed_Handler(srv interface{}, ctx context.Context, dec func(inte return interceptor(ctx, in, info, handler) } +func _Public_ListVehicles_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListVehiclesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PublicServer).ListVehicles(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/Public/ListVehicles", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PublicServer).ListVehicles(ctx, req.(*ListVehiclesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Public_GetVehicle_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetVehicleRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PublicServer).GetVehicle(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/Public/GetVehicle", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PublicServer).GetVehicle(ctx, req.(*GetVehicleRequest)) + } + return interceptor(ctx, in, info, handler) +} + // Public_ServiceDesc is the grpc.ServiceDesc for Public service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -807,6 +891,14 @@ var Public_ServiceDesc = grpc.ServiceDesc{ MethodName: "GetFeed", Handler: _Public_GetFeed_Handler, }, + { + MethodName: "ListVehicles", + Handler: _Public_ListVehicles_Handler, + }, + { + MethodName: "GetVehicle", + Handler: _Public_GetVehicle_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "api/public.proto", diff --git a/internal/gen/db/batch.go b/internal/gen/db/batch.go index 933578cd..47bf9fd2 100644 --- a/internal/gen/db/batch.go +++ b/internal/gen/db/batch.go @@ -68,7 +68,7 @@ func (b *MarkTripStopTimesPastBatchResults) Close() error { } const updateTrip = `-- name: UpdateTrip :batchexec -UPDATE trip SET +UPDATE trip SET feed_pk = $1, direction_id = $2, started_at = $3, diff --git a/internal/gen/db/models.go b/internal/gen/db/models.go index 45fe4eb7..3effb96c 100644 --- a/internal/gen/db/models.go +++ b/internal/gen/db/models.go @@ -260,16 +260,17 @@ type Vehicle struct { TripPk pgtype.Int8 Label pgtype.Text LicensePlate pgtype.Text - CurrentStatus string - Latitude pgtype.Float8 - Longitude pgtype.Float8 - Bearing pgtype.Float8 + CurrentStatus pgtype.Text + Latitude pgtype.Numeric + Longitude pgtype.Numeric + Bearing pgtype.Float4 Odometer pgtype.Float8 - Speed pgtype.Float8 + Speed pgtype.Float4 CongestionLevel string UpdatedAt pgtype.Timestamptz CurrentStopPk pgtype.Int8 CurrentStopSequence pgtype.Int4 - OccupancyStatus string + OccupancyStatus pgtype.Text FeedPk int64 + OccupancyPercentage pgtype.Int4 } diff --git a/internal/gen/db/querier.go b/internal/gen/db/querier.go index 7507cda5..09f69cfc 100644 --- a/internal/gen/db/querier.go +++ b/internal/gen/db/querier.go @@ -25,6 +25,7 @@ type Querier interface { DeleteStaleRoutes(ctx context.Context, arg DeleteStaleRoutesParams) error DeleteStaleStops(ctx context.Context, arg DeleteStaleStopsParams) error DeleteStaleTrips(ctx context.Context, arg DeleteStaleTripsParams) ([]int64, error) + DeleteStaleVehicles(ctx context.Context, arg DeleteStaleVehiclesParams) error DeleteStopHeadsignRules(ctx context.Context, feedPk int64) error DeleteSystem(ctx context.Context, pk int64) error DeleteTransfers(ctx context.Context, feedPk int64) error @@ -37,7 +38,8 @@ type Querier interface { GetRoute(ctx context.Context, arg GetRouteParams) (Route, error) GetStop(ctx context.Context, arg GetStopParams) (Stop, error) GetSystem(ctx context.Context, id string) (System, error) - GetTrip(ctx context.Context, arg GetTripParams) (Trip, error) + GetTrip(ctx context.Context, arg GetTripParams) (GetTripRow, error) + GetVehicle(ctx context.Context, arg GetVehicleParams) (GetVehicleRow, error) InsertAgency(ctx context.Context, arg InsertAgencyParams) (int64, error) InsertAlert(ctx context.Context, arg InsertAlertParams) (int64, error) InsertAlertActivePeriod(ctx context.Context, arg InsertAlertActivePeriodParams) error @@ -55,6 +57,7 @@ type Querier interface { InsertTransfer(ctx context.Context, arg InsertTransferParams) error InsertTrip(ctx context.Context, arg InsertTripParams) (int64, error) InsertTripStopTime(ctx context.Context, arg []InsertTripStopTimeParams) (int64, error) + InsertVehicle(ctx context.Context, arg InsertVehicleParams) error ListActiveAlertsForAgencies(ctx context.Context, arg ListActiveAlertsForAgenciesParams) ([]ListActiveAlertsForAgenciesRow, error) // ListActiveAlertsForRoutes returns preview information about active alerts for the provided routes. ListActiveAlertsForRoutes(ctx context.Context, arg ListActiveAlertsForRoutesParams) ([]ListActiveAlertsForRoutesRow, error) @@ -83,15 +86,20 @@ type Querier interface { ListSystems(ctx context.Context) ([]System, error) ListTransfersFromStops(ctx context.Context, fromStopPks []int64) ([]Transfer, error) ListTransfersInSystem(ctx context.Context, systemPk pgtype.Int8) ([]ListTransfersInSystemRow, error) + ListTripPksInSystem(ctx context.Context, arg ListTripPksInSystemParams) ([]ListTripPksInSystemRow, error) ListTripStopTimesByStops(ctx context.Context, stopPks []int64) ([]ListTripStopTimesByStopsRow, error) ListTripStopTimesForUpdate(ctx context.Context, tripPks []int64) ([]ListTripStopTimesForUpdateRow, error) - ListTrips(ctx context.Context, routePks []int64) ([]Trip, error) + ListTrips(ctx context.Context, routePks []int64) ([]ListTripsRow, error) + ListVehicleUniqueColumns(ctx context.Context, arg ListVehicleUniqueColumnsParams) ([]ListVehicleUniqueColumnsRow, error) + ListVehicles(ctx context.Context, arg ListVehiclesParams) ([]ListVehiclesRow, error) + ListVehicles_Geographic(ctx context.Context, arg ListVehicles_GeographicParams) ([]ListVehicles_GeographicRow, error) MapAgencyPkToId(ctx context.Context, systemPk int64) ([]MapAgencyPkToIdRow, error) MapRouteIDToPkInSystem(ctx context.Context, arg MapRouteIDToPkInSystemParams) ([]MapRouteIDToPkInSystemRow, error) MapStopIDAndPkToStationPk(ctx context.Context, arg MapStopIDAndPkToStationPkParams) ([]MapStopIDAndPkToStationPkRow, error) MapStopIDToPk(ctx context.Context, arg MapStopIDToPkParams) ([]MapStopIDToPkRow, error) MapStopPkToChildPks(ctx context.Context, stopPks []int64) ([]MapStopPkToChildPksRow, error) MapStopPkToDescendentPks(ctx context.Context, stopPks []int64) ([]MapStopPkToDescendentPksRow, error) + MapTripIDToPkInSystem(ctx context.Context, arg MapTripIDToPkInSystemParams) ([]MapTripIDToPkInSystemRow, error) MarkFailedUpdate(ctx context.Context, arg MarkFailedUpdateParams) error MarkSkippedUpdate(ctx context.Context, arg MarkSkippedUpdateParams) error MarkSuccessfulUpdate(ctx context.Context, arg MarkSuccessfulUpdateParams) error @@ -106,6 +114,7 @@ type Querier interface { UpdateSystemStatus(ctx context.Context, arg UpdateSystemStatusParams) error UpdateTrip(ctx context.Context, arg []UpdateTripParams) *UpdateTripBatchResults UpdateTripStopTime(ctx context.Context, arg UpdateTripStopTimeParams) error + UpdateVehicle(ctx context.Context, arg UpdateVehicleParams) error } var _ Querier = (*Queries)(nil) diff --git a/internal/gen/db/stop_queries.sql.go b/internal/gen/db/stop_queries.sql.go index de14cb54..b29e7726 100644 --- a/internal/gen/db/stop_queries.sql.go +++ b/internal/gen/db/stop_queries.sql.go @@ -13,7 +13,7 @@ import ( const deleteStaleStops = `-- name: DeleteStaleStops :exec DELETE FROM stop -WHERE +WHERE stop.feed_pk = $1 AND NOT stop.pk = ANY($2::bigint[]) ` @@ -219,7 +219,7 @@ func (q *Queries) ListStopsByPk(ctx context.Context, stopPks []int64) ([]ListSto const listStops_Geographic = `-- name: ListStops_Geographic :many WITH distance AS ( - SELECT + SELECT pk stop_pk, (6371 * acos(cos(radians(latitude)) * cos(radians($3::numeric)) * cos(radians($4::numeric) - radians(longitude)) + sin(radians(latitude)) * sin(radians($3::numeric)))) val FROM stop @@ -284,7 +284,13 @@ func (q *Queries) ListStops_Geographic(ctx context.Context, arg ListStops_Geogra } const listTripStopTimesByStops = `-- name: ListTripStopTimesByStops :many -SELECT trip_stop_time.pk, trip_stop_time.stop_pk, trip_stop_time.trip_pk, trip_stop_time.arrival_time, trip_stop_time.arrival_delay, trip_stop_time.arrival_uncertainty, trip_stop_time.departure_time, trip_stop_time.departure_delay, trip_stop_time.departure_uncertainty, trip_stop_time.stop_sequence, trip_stop_time.track, trip_stop_time.headsign, trip_stop_time.past, trip.pk, trip.id, trip.route_pk, trip.direction_id, trip.started_at, trip.gtfs_hash, trip.feed_pk, vehicle.id vehicle_id FROM trip_stop_time +SELECT trip_stop_time.pk, trip_stop_time.stop_pk, trip_stop_time.trip_pk, trip_stop_time.arrival_time, trip_stop_time.arrival_delay, trip_stop_time.arrival_uncertainty, trip_stop_time.departure_time, trip_stop_time.departure_delay, trip_stop_time.departure_uncertainty, trip_stop_time.stop_sequence, trip_stop_time.track, trip_stop_time.headsign, trip_stop_time.past, + trip.pk, trip.id, trip.route_pk, trip.direction_id, trip.started_at, trip.gtfs_hash, trip.feed_pk, vehicle.id vehicle_id, + vehicle.latitude vehicle_latitude, + vehicle.longitude vehicle_longitude, + vehicle.bearing vehicle_bearing, + vehicle.updated_at vehicle_updated_at + FROM trip_stop_time INNER JOIN trip ON trip_stop_time.trip_pk = trip.pk LEFT JOIN vehicle ON vehicle.trip_pk = trip.pk WHERE trip_stop_time.stop_pk = ANY($1::bigint[]) @@ -314,6 +320,10 @@ type ListTripStopTimesByStopsRow struct { GtfsHash string FeedPk int64 VehicleID pgtype.Text + VehicleLatitude pgtype.Numeric + VehicleLongitude pgtype.Numeric + VehicleBearing pgtype.Float4 + VehicleUpdatedAt pgtype.Timestamptz } func (q *Queries) ListTripStopTimesByStops(ctx context.Context, stopPks []int64) ([]ListTripStopTimesByStopsRow, error) { @@ -347,6 +357,10 @@ func (q *Queries) ListTripStopTimesByStops(ctx context.Context, stopPks []int64) &i.GtfsHash, &i.FeedPk, &i.VehicleID, + &i.VehicleLatitude, + &i.VehicleLongitude, + &i.VehicleBearing, + &i.VehicleUpdatedAt, ); err != nil { return nil, err } @@ -359,29 +373,29 @@ func (q *Queries) ListTripStopTimesByStops(ctx context.Context, stopPks []int64) } const mapStopIDAndPkToStationPk = `-- name: MapStopIDAndPkToStationPk :many -WITH RECURSIVE +WITH RECURSIVE ancestor AS ( - SELECT - id stop_id, + SELECT + id stop_id, pk stop_pk, - pk station_pk, + pk station_pk, parent_stop_pk, - (type = 'STATION') is_station + (type = 'STATION') is_station FROM stop WHERE stop.system_pk = $1 AND ( NOT $2::bool OR stop.pk = ANY($3::bigint[]) ) - UNION - SELECT + UNION + SELECT child.stop_id stop_id, child.stop_pk stop_pk, - parent.pk station_pk, - parent.parent_stop_pk, - (parent.type = 'STATION') is_station - FROM stop parent - INNER JOIN ancestor child + parent.pk station_pk, + parent.parent_stop_pk, + (parent.type = 'STATION') is_station + FROM stop parent + INNER JOIN ancestor child ON child.parent_stop_pk = parent.pk AND NOT child.is_station ) @@ -497,17 +511,17 @@ func (q *Queries) MapStopPkToChildPks(ctx context.Context, stopPks []int64) ([]M const mapStopPkToDescendentPks = `-- name: MapStopPkToDescendentPks :many WITH RECURSIVE descendent AS ( - SELECT + SELECT stop.pk root_stop_pk, stop.pk descendent_stop_pk FROM stop WHERE stop.pk = ANY($1::bigint[]) - UNION - SELECT + UNION + SELECT descendent.root_stop_pk root_stop_pk, child.pk descendent_stop_pk - FROM stop child - INNER JOIN descendent + FROM stop child + INNER JOIN descendent ON child.parent_stop_pk = descendent.descendent_stop_pk ) SELECT root_stop_pk, descendent_stop_pk FROM descendent @@ -548,8 +562,8 @@ UPDATE stop SET code = $6, description = $7, platform_code = $8, - timezone = $9, - type = $10, + timezone = $9, + type = $10, wheelchair_boarding = $11, zone_id = $12, parent_stop_pk = NULL diff --git a/internal/gen/db/trip_queries.sql.go b/internal/gen/db/trip_queries.sql.go index fa7d5af0..8a3ab38e 100644 --- a/internal/gen/db/trip_queries.sql.go +++ b/internal/gen/db/trip_queries.sql.go @@ -13,7 +13,7 @@ import ( const deleteStaleTrips = `-- name: DeleteStaleTrips :many DELETE FROM trip -WHERE +WHERE trip.feed_pk = $1 AND NOT trip.pk = ANY($2::bigint[]) RETURNING trip.route_pk @@ -96,7 +96,14 @@ func (q *Queries) GetDestinationsForTrips(ctx context.Context, tripPks []int64) } const getTrip = `-- name: GetTrip :one -SELECT pk, id, route_pk, direction_id, started_at, gtfs_hash, feed_pk FROM trip +SELECT trip.pk, trip.id, trip.route_pk, trip.direction_id, trip.started_at, trip.gtfs_hash, trip.feed_pk, + vehicle.id as vehicle_id, + vehicle.latitude as vehicle_latitude, + vehicle.longitude as vehicle_longitude, + vehicle.bearing as vehicle_bearing, + vehicle.updated_at as vehicle_updated_at +FROM trip +LEFT JOIN vehicle ON trip.pk = vehicle.trip_pk WHERE trip.id = $1 AND trip.route_pk = $2 ` @@ -106,9 +113,24 @@ type GetTripParams struct { RoutePk int64 } -func (q *Queries) GetTrip(ctx context.Context, arg GetTripParams) (Trip, error) { +type GetTripRow struct { + Pk int64 + ID string + RoutePk int64 + DirectionID pgtype.Bool + StartedAt pgtype.Timestamptz + GtfsHash string + FeedPk int64 + VehicleID pgtype.Text + VehicleLatitude pgtype.Numeric + VehicleLongitude pgtype.Numeric + VehicleBearing pgtype.Float4 + VehicleUpdatedAt pgtype.Timestamptz +} + +func (q *Queries) GetTrip(ctx context.Context, arg GetTripParams) (GetTripRow, error) { row := q.db.QueryRow(ctx, getTrip, arg.TripID, arg.RoutePk) - var i Trip + var i GetTripRow err := row.Scan( &i.Pk, &i.ID, @@ -117,6 +139,11 @@ func (q *Queries) GetTrip(ctx context.Context, arg GetTripParams) (Trip, error) &i.StartedAt, &i.GtfsHash, &i.FeedPk, + &i.VehicleID, + &i.VehicleLatitude, + &i.VehicleLongitude, + &i.VehicleBearing, + &i.VehicleUpdatedAt, ) return i, err } @@ -229,6 +256,44 @@ func (q *Queries) ListStopsTimesForTrip(ctx context.Context, tripPk int64) ([]Li return items, nil } +const listTripPksInSystem = `-- name: ListTripPksInSystem :many +SELECT trip.id, trip.pk +FROM trip + INNER JOIN feed ON trip.feed_pk = feed.pk +WHERE trip.id = ANY($1::text[]) + AND feed.system_pk = $2 +` + +type ListTripPksInSystemParams struct { + TripIds []string + SystemPk int64 +} + +type ListTripPksInSystemRow struct { + ID string + Pk int64 +} + +func (q *Queries) ListTripPksInSystem(ctx context.Context, arg ListTripPksInSystemParams) ([]ListTripPksInSystemRow, error) { + rows, err := q.db.Query(ctx, listTripPksInSystem, arg.TripIds, arg.SystemPk) + if err != nil { + return nil, err + } + defer rows.Close() + var items []ListTripPksInSystemRow + for rows.Next() { + var i ListTripPksInSystemRow + if err := rows.Scan(&i.ID, &i.Pk); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + const listTripStopTimesForUpdate = `-- name: ListTripStopTimesForUpdate :many SELECT pk, trip_pk, stop_pk, stop_sequence, past FROM trip_stop_time WHERE trip_pk = ANY($1::bigint[]) @@ -270,20 +335,42 @@ func (q *Queries) ListTripStopTimesForUpdate(ctx context.Context, tripPks []int6 } const listTrips = `-- name: ListTrips :many -SELECT pk, id, route_pk, direction_id, started_at, gtfs_hash, feed_pk FROM trip +SELECT trip.pk, trip.id, trip.route_pk, trip.direction_id, trip.started_at, trip.gtfs_hash, trip.feed_pk, + vehicle.id as vehicle_id, + vehicle.latitude as vehicle_latitude, + vehicle.longitude as vehicle_longitude, + vehicle.bearing as vehicle_bearing, + vehicle.updated_at as vehicle_updated_at +FROM trip +LEFT JOIN vehicle ON trip.pk = vehicle.trip_pk WHERE route_pk = ANY($1::bigint[]) ORDER BY route_pk, id ` -func (q *Queries) ListTrips(ctx context.Context, routePks []int64) ([]Trip, error) { +type ListTripsRow struct { + Pk int64 + ID string + RoutePk int64 + DirectionID pgtype.Bool + StartedAt pgtype.Timestamptz + GtfsHash string + FeedPk int64 + VehicleID pgtype.Text + VehicleLatitude pgtype.Numeric + VehicleLongitude pgtype.Numeric + VehicleBearing pgtype.Float4 + VehicleUpdatedAt pgtype.Timestamptz +} + +func (q *Queries) ListTrips(ctx context.Context, routePks []int64) ([]ListTripsRow, error) { rows, err := q.db.Query(ctx, listTrips, routePks) if err != nil { return nil, err } defer rows.Close() - var items []Trip + var items []ListTripsRow for rows.Next() { - var i Trip + var i ListTripsRow if err := rows.Scan( &i.Pk, &i.ID, @@ -292,6 +379,11 @@ func (q *Queries) ListTrips(ctx context.Context, routePks []int64) ([]Trip, erro &i.StartedAt, &i.GtfsHash, &i.FeedPk, + &i.VehicleID, + &i.VehicleLatitude, + &i.VehicleLongitude, + &i.VehicleBearing, + &i.VehicleUpdatedAt, ); err != nil { return nil, err } @@ -303,6 +395,45 @@ func (q *Queries) ListTrips(ctx context.Context, routePks []int64) ([]Trip, erro return items, nil } +const mapTripIDToPkInSystem = `-- name: MapTripIDToPkInSystem :many +SELECT trip.id, trip.pk +FROM trip + INNER JOIN feed ON trip.feed_pk = feed.pk +WHERE trip.id = ANY($1::text[]) + AND feed.system_pk = $2 +FOR UPDATE +` + +type MapTripIDToPkInSystemParams struct { + TripIds []string + SystemPk int64 +} + +type MapTripIDToPkInSystemRow struct { + ID string + Pk int64 +} + +func (q *Queries) MapTripIDToPkInSystem(ctx context.Context, arg MapTripIDToPkInSystemParams) ([]MapTripIDToPkInSystemRow, error) { + rows, err := q.db.Query(ctx, mapTripIDToPkInSystem, arg.TripIds, arg.SystemPk) + if err != nil { + return nil, err + } + defer rows.Close() + var items []MapTripIDToPkInSystemRow + for rows.Next() { + var i MapTripIDToPkInSystemRow + if err := rows.Scan(&i.ID, &i.Pk); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + const updateTripStopTime = `-- name: UpdateTripStopTime :exec UPDATE trip_stop_time SET diff --git a/internal/gen/db/vehicle_queries.sql.go b/internal/gen/db/vehicle_queries.sql.go new file mode 100644 index 00000000..26ac4eaf --- /dev/null +++ b/internal/gen/db/vehicle_queries.sql.go @@ -0,0 +1,486 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.17.2 +// source: vehicle_queries.sql + +package db + +import ( + "context" + + "github.com/jackc/pgx/v5/pgtype" +) + +const deleteStaleVehicles = `-- name: DeleteStaleVehicles :exec +DELETE FROM vehicle +WHERE + feed_pk = $1 + AND NOT id = ANY($2::text[]) +` + +type DeleteStaleVehiclesParams struct { + FeedPk int64 + ActiveVehicleIds []string +} + +func (q *Queries) DeleteStaleVehicles(ctx context.Context, arg DeleteStaleVehiclesParams) error { + _, err := q.db.Exec(ctx, deleteStaleVehicles, arg.FeedPk, arg.ActiveVehicleIds) + return err +} + +const getVehicle = `-- name: GetVehicle :one +SELECT vehicle.pk, vehicle.id, vehicle.system_pk, vehicle.trip_pk, vehicle.label, vehicle.license_plate, vehicle.current_status, vehicle.latitude, vehicle.longitude, vehicle.bearing, vehicle.odometer, vehicle.speed, vehicle.congestion_level, vehicle.updated_at, vehicle.current_stop_pk, vehicle.current_stop_sequence, vehicle.occupancy_status, vehicle.feed_pk, vehicle.occupancy_percentage, + stop.id as stop_id, + stop.name as stop_name, + trip.id as trip_id, + trip.direction_id as trip_direction_id, + route.id as route_id, + route.color as route_color +FROM vehicle +LEFT JOIN stop ON vehicle.current_stop_pk = stop.pk +LEFT JOIN trip ON vehicle.trip_pk = trip.pk +LEFT JOIN route ON trip.route_pk = route.pk +WHERE vehicle.system_pk = $1 AND vehicle.id = $2 +` + +type GetVehicleParams struct { + SystemPk int64 + VehicleID pgtype.Text +} + +type GetVehicleRow struct { + Pk int64 + ID pgtype.Text + SystemPk int64 + TripPk pgtype.Int8 + Label pgtype.Text + LicensePlate pgtype.Text + CurrentStatus pgtype.Text + Latitude pgtype.Numeric + Longitude pgtype.Numeric + Bearing pgtype.Float4 + Odometer pgtype.Float8 + Speed pgtype.Float4 + CongestionLevel string + UpdatedAt pgtype.Timestamptz + CurrentStopPk pgtype.Int8 + CurrentStopSequence pgtype.Int4 + OccupancyStatus pgtype.Text + FeedPk int64 + OccupancyPercentage pgtype.Int4 + StopID pgtype.Text + StopName pgtype.Text + TripID pgtype.Text + TripDirectionID pgtype.Bool + RouteID pgtype.Text + RouteColor pgtype.Text +} + +func (q *Queries) GetVehicle(ctx context.Context, arg GetVehicleParams) (GetVehicleRow, error) { + row := q.db.QueryRow(ctx, getVehicle, arg.SystemPk, arg.VehicleID) + var i GetVehicleRow + err := row.Scan( + &i.Pk, + &i.ID, + &i.SystemPk, + &i.TripPk, + &i.Label, + &i.LicensePlate, + &i.CurrentStatus, + &i.Latitude, + &i.Longitude, + &i.Bearing, + &i.Odometer, + &i.Speed, + &i.CongestionLevel, + &i.UpdatedAt, + &i.CurrentStopPk, + &i.CurrentStopSequence, + &i.OccupancyStatus, + &i.FeedPk, + &i.OccupancyPercentage, + &i.StopID, + &i.StopName, + &i.TripID, + &i.TripDirectionID, + &i.RouteID, + &i.RouteColor, + ) + return i, err +} + +const insertVehicle = `-- name: InsertVehicle :exec +INSERT INTO vehicle + (id, system_pk, trip_pk, label, license_plate, current_status, latitude, longitude, bearing, odometer, speed, congestion_level, updated_at, current_stop_pk, current_stop_sequence, occupancy_status, feed_pk, occupancy_percentage) +VALUES + ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18) +` + +type InsertVehicleParams struct { + ID pgtype.Text + SystemPk int64 + TripPk pgtype.Int8 + Label pgtype.Text + LicensePlate pgtype.Text + CurrentStatus pgtype.Text + Latitude pgtype.Numeric + Longitude pgtype.Numeric + Bearing pgtype.Float4 + Odometer pgtype.Float8 + Speed pgtype.Float4 + CongestionLevel string + UpdatedAt pgtype.Timestamptz + CurrentStopPk pgtype.Int8 + CurrentStopSequence pgtype.Int4 + OccupancyStatus pgtype.Text + FeedPk int64 + OccupancyPercentage pgtype.Int4 +} + +func (q *Queries) InsertVehicle(ctx context.Context, arg InsertVehicleParams) error { + _, err := q.db.Exec(ctx, insertVehicle, + arg.ID, + arg.SystemPk, + arg.TripPk, + arg.Label, + arg.LicensePlate, + arg.CurrentStatus, + arg.Latitude, + arg.Longitude, + arg.Bearing, + arg.Odometer, + arg.Speed, + arg.CongestionLevel, + arg.UpdatedAt, + arg.CurrentStopPk, + arg.CurrentStopSequence, + arg.OccupancyStatus, + arg.FeedPk, + arg.OccupancyPercentage, + ) + return err +} + +const listVehicleUniqueColumns = `-- name: ListVehicleUniqueColumns :many +SELECT id, pk, trip_pk FROM vehicle +WHERE id = ANY($1::text[]) +AND system_pk = $2 +` + +type ListVehicleUniqueColumnsParams struct { + VehicleIds []string + SystemPk int64 +} + +type ListVehicleUniqueColumnsRow struct { + ID pgtype.Text + Pk int64 + TripPk pgtype.Int8 +} + +func (q *Queries) ListVehicleUniqueColumns(ctx context.Context, arg ListVehicleUniqueColumnsParams) ([]ListVehicleUniqueColumnsRow, error) { + rows, err := q.db.Query(ctx, listVehicleUniqueColumns, arg.VehicleIds, arg.SystemPk) + if err != nil { + return nil, err + } + defer rows.Close() + var items []ListVehicleUniqueColumnsRow + for rows.Next() { + var i ListVehicleUniqueColumnsRow + if err := rows.Scan(&i.ID, &i.Pk, &i.TripPk); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listVehicles = `-- name: ListVehicles :many +SELECT vehicle.pk, vehicle.id, vehicle.system_pk, vehicle.trip_pk, vehicle.label, vehicle.license_plate, vehicle.current_status, vehicle.latitude, vehicle.longitude, vehicle.bearing, vehicle.odometer, vehicle.speed, vehicle.congestion_level, vehicle.updated_at, vehicle.current_stop_pk, vehicle.current_stop_sequence, vehicle.occupancy_status, vehicle.feed_pk, vehicle.occupancy_percentage, + stop.id as stop_id, + stop.name as stop_name, + trip.id as trip_id, + trip.direction_id as trip_direction_id, + route.id as route_id, + route.color as route_color +FROM vehicle +LEFT JOIN stop ON vehicle.current_stop_pk = stop.pk +LEFT JOIN trip ON vehicle.trip_pk = trip.pk +LEFT JOIN route ON trip.route_pk = route.pk +WHERE vehicle.system_pk = $1 + AND vehicle.id >= $2 + AND ( + NOT $3::bool OR + vehicle.id = ANY($4::text[]) + ) +ORDER BY vehicle.id +LIMIT $5 +` + +type ListVehiclesParams struct { + SystemPk int64 + FirstVehicleID pgtype.Text + OnlyReturnSpecifiedIds bool + VehicleIds []string + NumVehicles int32 +} + +type ListVehiclesRow struct { + Pk int64 + ID pgtype.Text + SystemPk int64 + TripPk pgtype.Int8 + Label pgtype.Text + LicensePlate pgtype.Text + CurrentStatus pgtype.Text + Latitude pgtype.Numeric + Longitude pgtype.Numeric + Bearing pgtype.Float4 + Odometer pgtype.Float8 + Speed pgtype.Float4 + CongestionLevel string + UpdatedAt pgtype.Timestamptz + CurrentStopPk pgtype.Int8 + CurrentStopSequence pgtype.Int4 + OccupancyStatus pgtype.Text + FeedPk int64 + OccupancyPercentage pgtype.Int4 + StopID pgtype.Text + StopName pgtype.Text + TripID pgtype.Text + TripDirectionID pgtype.Bool + RouteID pgtype.Text + RouteColor pgtype.Text +} + +func (q *Queries) ListVehicles(ctx context.Context, arg ListVehiclesParams) ([]ListVehiclesRow, error) { + rows, err := q.db.Query(ctx, listVehicles, + arg.SystemPk, + arg.FirstVehicleID, + arg.OnlyReturnSpecifiedIds, + arg.VehicleIds, + arg.NumVehicles, + ) + if err != nil { + return nil, err + } + defer rows.Close() + var items []ListVehiclesRow + for rows.Next() { + var i ListVehiclesRow + if err := rows.Scan( + &i.Pk, + &i.ID, + &i.SystemPk, + &i.TripPk, + &i.Label, + &i.LicensePlate, + &i.CurrentStatus, + &i.Latitude, + &i.Longitude, + &i.Bearing, + &i.Odometer, + &i.Speed, + &i.CongestionLevel, + &i.UpdatedAt, + &i.CurrentStopPk, + &i.CurrentStopSequence, + &i.OccupancyStatus, + &i.FeedPk, + &i.OccupancyPercentage, + &i.StopID, + &i.StopName, + &i.TripID, + &i.TripDirectionID, + &i.RouteID, + &i.RouteColor, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listVehicles_Geographic = `-- name: ListVehicles_Geographic :many +WITH distance AS ( + SELECT + pk vehicle_pk, + (6371 * acos(cos(radians(latitude)) * cos(radians($3::numeric)) * cos(radians($4::numeric) - radians(longitude)) + sin(radians(latitude)) * sin(radians($3::numeric)))) val + FROM vehicle + WHERE vehicle.system_pk = $5 AND latitude IS NOT NULL AND longitude IS NOT NULL +) +SELECT vehicle.pk, vehicle.id, vehicle.system_pk, vehicle.trip_pk, vehicle.label, vehicle.license_plate, vehicle.current_status, vehicle.latitude, vehicle.longitude, vehicle.bearing, vehicle.odometer, vehicle.speed, vehicle.congestion_level, vehicle.updated_at, vehicle.current_stop_pk, vehicle.current_stop_sequence, vehicle.occupancy_status, vehicle.feed_pk, vehicle.occupancy_percentage, + stop.id as stop_id, + stop.name as stop_name, + trip.id as trip_id, + trip.direction_id as trip_direction_id, + route.id as route_id, + route.color as route_color +FROM vehicle +INNER JOIN distance ON vehicle.pk = distance.vehicle_pk +AND distance.val <= $1::numeric +LEFT JOIN stop ON vehicle.current_stop_pk = stop.pk +LEFT JOIN trip ON vehicle.trip_pk = trip.pk +LEFT JOIN route ON trip.route_pk = route.pk +ORDER BY distance.val +LIMIT $2 +` + +type ListVehicles_GeographicParams struct { + MaxDistance pgtype.Numeric + NumVehicles int32 + Latitude pgtype.Numeric + Longitude pgtype.Numeric + SystemPk int64 +} + +type ListVehicles_GeographicRow struct { + Pk int64 + ID pgtype.Text + SystemPk int64 + TripPk pgtype.Int8 + Label pgtype.Text + LicensePlate pgtype.Text + CurrentStatus pgtype.Text + Latitude pgtype.Numeric + Longitude pgtype.Numeric + Bearing pgtype.Float4 + Odometer pgtype.Float8 + Speed pgtype.Float4 + CongestionLevel string + UpdatedAt pgtype.Timestamptz + CurrentStopPk pgtype.Int8 + CurrentStopSequence pgtype.Int4 + OccupancyStatus pgtype.Text + FeedPk int64 + OccupancyPercentage pgtype.Int4 + StopID pgtype.Text + StopName pgtype.Text + TripID pgtype.Text + TripDirectionID pgtype.Bool + RouteID pgtype.Text + RouteColor pgtype.Text +} + +func (q *Queries) ListVehicles_Geographic(ctx context.Context, arg ListVehicles_GeographicParams) ([]ListVehicles_GeographicRow, error) { + rows, err := q.db.Query(ctx, listVehicles_Geographic, + arg.MaxDistance, + arg.NumVehicles, + arg.Latitude, + arg.Longitude, + arg.SystemPk, + ) + if err != nil { + return nil, err + } + defer rows.Close() + var items []ListVehicles_GeographicRow + for rows.Next() { + var i ListVehicles_GeographicRow + if err := rows.Scan( + &i.Pk, + &i.ID, + &i.SystemPk, + &i.TripPk, + &i.Label, + &i.LicensePlate, + &i.CurrentStatus, + &i.Latitude, + &i.Longitude, + &i.Bearing, + &i.Odometer, + &i.Speed, + &i.CongestionLevel, + &i.UpdatedAt, + &i.CurrentStopPk, + &i.CurrentStopSequence, + &i.OccupancyStatus, + &i.FeedPk, + &i.OccupancyPercentage, + &i.StopID, + &i.StopName, + &i.TripID, + &i.TripDirectionID, + &i.RouteID, + &i.RouteColor, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const updateVehicle = `-- name: UpdateVehicle :exec +UPDATE vehicle +SET trip_pk = $1, + label = $2, + license_plate = $3, + current_status = $4, + latitude = $5, + longitude = $6, + bearing = $7, + odometer = $8, + speed = $9, + congestion_level = $10, + updated_at = $11, + current_stop_pk = $12, + current_stop_sequence = $13, + occupancy_status = $14, + feed_pk = $15, + occupancy_percentage = $16 +WHERE vehicle.pk = $17 +` + +type UpdateVehicleParams struct { + TripPk pgtype.Int8 + Label pgtype.Text + LicensePlate pgtype.Text + CurrentStatus pgtype.Text + Latitude pgtype.Numeric + Longitude pgtype.Numeric + Bearing pgtype.Float4 + Odometer pgtype.Float8 + Speed pgtype.Float4 + CongestionLevel string + UpdatedAt pgtype.Timestamptz + CurrentStopPk pgtype.Int8 + CurrentStopSequence pgtype.Int4 + OccupancyStatus pgtype.Text + FeedPk int64 + OccupancyPercentage pgtype.Int4 + Pk int64 +} + +func (q *Queries) UpdateVehicle(ctx context.Context, arg UpdateVehicleParams) error { + _, err := q.db.Exec(ctx, updateVehicle, + arg.TripPk, + arg.Label, + arg.LicensePlate, + arg.CurrentStatus, + arg.Latitude, + arg.Longitude, + arg.Bearing, + arg.Odometer, + arg.Speed, + arg.CongestionLevel, + arg.UpdatedAt, + arg.CurrentStopPk, + arg.CurrentStopSequence, + arg.OccupancyStatus, + arg.FeedPk, + arg.OccupancyPercentage, + arg.Pk, + ) + return err +} diff --git a/internal/public/endpoints/context.go b/internal/public/endpoints/context.go index fa169969..a7e548f0 100644 --- a/internal/public/endpoints/context.go +++ b/internal/public/endpoints/context.go @@ -15,6 +15,9 @@ type EndpointOptions struct { // The maximum number of stops that can be returned in a single request. // Defaults to 100. MaxStopsPerRequest int32 + // The maximum number of vehicles that can be returned in a single request. + // Defaults to 100. + MaxVehiclesPerRequest int32 } type Context struct { diff --git a/internal/public/endpoints/stop.go b/internal/public/endpoints/stop.go index 2602117f..0cb5bbab 100644 --- a/internal/public/endpoints/stop.go +++ b/internal/public/endpoints/stop.go @@ -137,7 +137,7 @@ func buildStopsResponse(ctx context.Context, r *Context, systemID string, stops stopPkToApiTransfers := buildStopPkToApiTransfers(data, stopPkToApiPreview) stopPkToApiServiceMaps := buildStopPkToApiServiceMaps(data, routePkToApiPreview) stopPkToApiAlerts := buildStopPkToApiAlerts(r, systemID, data) - stopPkToApiStopTimes := buildStopPkToApiStopsTimes(r, data, routePkToApiPreview, stopPkToApiPreview) + stopPkToApiStopTimes := buildStopPkToApiStopsTimes(r, data, routePkToApiPreview, stopPkToApiPreview, systemID) stopPkToApiHeadsignRules := buildStopPkToApiHeadsignRules(data, stopPkToApiPreview) stopPkToChildren := map[int64][]*api.Stop_Reference{} for stopPk, childPks := range data.stopPkToChildPks { @@ -354,7 +354,12 @@ func buildStopPkToApiAlerts(r *Context, systemID string, data rawStopData) map[i return liftToAncestors(data, m) } -func buildStopPkToApiStopsTimes(r *Context, data rawStopData, routePkToApiPreview map[int64]*api.Route_Reference, stopPkToApiPreview map[int64]*api.Stop_Reference) map[int64][]*api.StopTime { +func buildStopPkToApiStopsTimes( + r *Context, + data rawStopData, + routePkToApiPreview map[int64]*api.Route_Reference, + stopPkToApiPreview map[int64]*api.Stop_Reference, + systemID string) map[int64][]*api.StopTime { m := map[int64][]*api.StopTime{} tripPkToDestination := map[int64]*api.Stop_Reference{} for _, row := range data.tripDestinations { @@ -373,11 +378,15 @@ func buildStopPkToApiStopsTimes(r *Context, data rawStopData, routePkToApiPrevie stopTime.ID, routePkToApiPreview[stopTime.RoutePk], tripPkToDestination[stopTime.TripPk], - nil, // TODO: vehice + nil, stopTime.DirectionID.Bool, ), Stop: stopPkToApiPreview[stopTime.StopPk], } + if stopTime.VehicleID.Valid { + apiStopTime.Trip.Vehicle = r.Reference.Vehicle(stopTime.VehicleID.String, systemID) + } + m[stopTime.StopPk] = append(m[stopTime.StopPk], apiStopTime) } return liftToAncestors(data, m) diff --git a/internal/public/endpoints/trip.go b/internal/public/endpoints/trip.go index bbccdfc0..898a7a7a 100644 --- a/internal/public/endpoints/trip.go +++ b/internal/public/endpoints/trip.go @@ -45,14 +45,25 @@ func GetTrip(ctx context.Context, r *Context, req *api.GetTripRequest) (*api.Tri } return nil, err } - apiTrips, err := buildApiTrips(ctx, r, &system, &route, []db.Trip{trip}) + apiTrips, err := buildApiTrips(ctx, r, &system, &route, []db.ListTripsRow{{ + Pk: trip.Pk, + ID: trip.ID, + RoutePk: trip.RoutePk, + DirectionID: trip.DirectionID, + StartedAt: trip.StartedAt, + GtfsHash: trip.GtfsHash, + FeedPk: trip.FeedPk, + VehicleID: trip.VehicleID, + VehicleLatitude: trip.VehicleLatitude, + VehicleLongitude: trip.VehicleLongitude, + }}) if err != nil { return nil, err } return apiTrips[0], nil } -func buildApiTrips(ctx context.Context, r *Context, system *db.System, route *db.Route, trips []db.Trip) ([]*api.Trip, error) { +func buildApiTrips(ctx context.Context, r *Context, system *db.System, route *db.Route, trips []db.ListTripsRow) ([]*api.Trip, error) { var apiTrips []*api.Trip for i := range trips { trip := &trips[i] @@ -66,10 +77,9 @@ func buildApiTrips(ctx context.Context, r *Context, system *db.System, route *db StartedAt: convert.SQLNullTime(trip.StartedAt), Route: r.Reference.Route(route.ID, system.ID, route.Color), } - // TODO: vechices - // if trip.VehicleID.Valid { - // reply.Vehicle = r.Reference.Vehicle(trip.VehicleID.String) - //} + if trip.VehicleID.Valid { + reply.Vehicle = r.Reference.Vehicle(trip.VehicleID.String, system.ID) + } for _, stopTime := range stopTimes { reply.StopTimes = append(reply.StopTimes, &api.StopTime{ StopSequence: stopTime.StopSequence, diff --git a/internal/public/endpoints/vehicle.go b/internal/public/endpoints/vehicle.go new file mode 100644 index 00000000..c1b5771e --- /dev/null +++ b/internal/public/endpoints/vehicle.go @@ -0,0 +1,207 @@ +package endpoints + +import ( + "context" + "math" + + "github.com/jackc/pgx/v5/pgtype" + "github.com/jamespfennell/transiter/internal/convert" + "github.com/jamespfennell/transiter/internal/gen/api" + "github.com/jamespfennell/transiter/internal/gen/db" + "github.com/jamespfennell/transiter/internal/public/errors" +) + +func ListVehicles(ctx context.Context, r *Context, req *api.ListVehiclesRequest) (*api.ListVehiclesReply, error) { + system, err := getSystem(ctx, r.Querier, req.SystemId) + if err != nil { + return nil, err + } + + numVehicles := r.EndpointOptions.MaxVehiclesPerRequest + if numVehicles <= 0 { + numVehicles = math.MaxInt32 - 1 + } + if req.Limit != nil && *req.Limit < numVehicles { + numVehicles = *req.Limit + } + var firstID string + if req.FirstId != nil { + firstID = *req.FirstId + } + + var dbVehicles []db.ListVehiclesRow + if req.GetSearchMode() == api.ListVehiclesRequest_DISTANCE { + if req.Latitude == nil || req.Longitude == nil || req.MaxDistance == nil { + return nil, errors.NewInvalidArgumentError("latitude, longitude, and max_distance are required when using DISTANCE search_mode") + } + if firstID != "" { + return nil, errors.NewInvalidArgumentError("first_id can not be used when using DISTANCE search_mode") + } + dbVehiclesGeo, err := r.Querier.ListVehicles_Geographic(ctx, db.ListVehicles_GeographicParams{ + SystemPk: system.Pk, + NumVehicles: numVehicles, + Latitude: convert.Gps(req.Latitude), + Longitude: convert.Gps(req.Longitude), + MaxDistance: convert.Gps(req.MaxDistance), + }) + + for _, dbVehicle := range dbVehiclesGeo { + dbVehicles = append(dbVehicles, db.ListVehiclesRow{ + ID: dbVehicle.ID, + Label: dbVehicle.Label, + LicensePlate: dbVehicle.LicensePlate, + CurrentStatus: dbVehicle.CurrentStatus, + Latitude: dbVehicle.Latitude, + Longitude: dbVehicle.Longitude, + Bearing: dbVehicle.Bearing, + Odometer: dbVehicle.Odometer, + Speed: dbVehicle.Speed, + CongestionLevel: dbVehicle.CongestionLevel, + UpdatedAt: dbVehicle.UpdatedAt, + CurrentStopSequence: dbVehicle.CurrentStopSequence, + OccupancyStatus: dbVehicle.OccupancyStatus, + OccupancyPercentage: dbVehicle.OccupancyPercentage, + StopID: dbVehicle.StopID, + StopName: dbVehicle.StopName, + TripID: dbVehicle.TripID, + TripDirectionID: dbVehicle.TripDirectionID, + RouteID: dbVehicle.RouteID, + RouteColor: dbVehicle.RouteColor, + }) + } + + if err != nil { + return nil, err + } + } else { + dbVehicles, err = r.Querier.ListVehicles(ctx, db.ListVehiclesParams{ + SystemPk: system.Pk, + FirstVehicleID: convert.NullString(&firstID), + NumVehicles: numVehicles + 1, + OnlyReturnSpecifiedIds: req.OnlyReturnSpecifiedIds, + VehicleIds: req.Id, + }) + if err != nil { + return nil, err + } + } + + apiVehicles, err := buildApiVehicles(ctx, r, &system, dbVehicles) + if err != nil { + return nil, err + } + + var nextID *string + if len(apiVehicles) == int(numVehicles+1) { + nextID = &apiVehicles[len(apiVehicles)-1].Id + apiVehicles = apiVehicles[:len(apiVehicles)-1] + } + + return &api.ListVehiclesReply{ + Vehicles: apiVehicles, + NextId: nextID, + }, nil +} + +func GetVehicle(ctx context.Context, r *Context, req *api.GetVehicleRequest) (*api.Vehicle, error) { + system, err := getSystem(ctx, r.Querier, req.SystemId) + if err != nil { + return nil, err + } + + dbVehicle, err := r.Querier.GetVehicle(ctx, db.GetVehicleParams{ + SystemPk: system.Pk, + VehicleID: convert.NullString(&req.VehicleId), + }) + if err != nil { + return nil, err + } + + apiVehicles, err := buildApiVehicles(ctx, r, &system, []db.ListVehiclesRow{ + { + ID: dbVehicle.ID, + Label: dbVehicle.Label, + LicensePlate: dbVehicle.LicensePlate, + CurrentStatus: dbVehicle.CurrentStatus, + Latitude: dbVehicle.Latitude, + Longitude: dbVehicle.Longitude, + Bearing: dbVehicle.Bearing, + Odometer: dbVehicle.Odometer, + Speed: dbVehicle.Speed, + CongestionLevel: dbVehicle.CongestionLevel, + UpdatedAt: dbVehicle.UpdatedAt, + CurrentStopSequence: dbVehicle.CurrentStopSequence, + OccupancyPercentage: dbVehicle.OccupancyPercentage, + OccupancyStatus: dbVehicle.OccupancyStatus, + StopID: dbVehicle.StopID, + StopName: dbVehicle.StopName, + TripID: dbVehicle.TripID, + TripDirectionID: dbVehicle.TripDirectionID, + RouteID: dbVehicle.RouteID, + RouteColor: dbVehicle.RouteColor, + }, + }) + if err != nil { + return nil, err + } + + return apiVehicles[0], nil +} + +func buildApiVehicles( + ctx context.Context, + r *Context, + system *db.System, + vehicles []db.ListVehiclesRow) ([]*api.Vehicle, error) { + var apiVehicles []*api.Vehicle + for i := range vehicles { + vehicle := &vehicles[i] + apiVehicles = append(apiVehicles, &api.Vehicle{ + Id: *convert.SQLNullString(vehicle.ID), + Trip: nullTripReferences( + r, + vehicle.TripID, + nullRouteReferences(r, vehicle.RouteID, vehicle.RouteColor, system.ID), + vehicle.TripDirectionID.Bool, + ), + Latitude: convert.SQLGps(vehicle.Latitude), + Longitude: convert.SQLGps(vehicle.Longitude), + Bearing: convert.SQLNullFloat4(vehicle.Bearing), + Odometer: convert.SQLNullFloat8(vehicle.Odometer), + Speed: convert.SQLNullFloat4(vehicle.Speed), + StopSequence: convert.SQLNullInt32(vehicle.CurrentStopSequence), + Stop: nullStopReference(r, vehicle.StopID, vehicle.StopName, system.ID), + CurrentStatus: convert.NullApiCurrentStatus(vehicle.CurrentStatus), + UpdatedAt: convert.SQLNullTime(vehicle.UpdatedAt), + CongestionLevel: convert.ApiCongestionLevel(vehicle.CongestionLevel), + OccupancyStatus: convert.NullApiOccupancyStatus(vehicle.OccupancyStatus), + }) + } + + return apiVehicles, nil +} + +func nullTripReferences( + r *Context, + tripID pgtype.Text, + routeRef *api.Route_Reference, + directionID bool) *api.Trip_Reference { + if !tripID.Valid || routeRef == nil { + return nil + } + return r.Reference.Trip(tripID.String, routeRef, nil, nil, directionID) +} + +func nullRouteReferences(r *Context, routeID pgtype.Text, routeColor pgtype.Text, systemID string) *api.Route_Reference { + if !routeID.Valid { + return nil + } + return r.Reference.Route(routeID.String, systemID, *convert.SQLNullString(routeColor)) +} + +func nullStopReference(r *Context, stopID pgtype.Text, stopName pgtype.Text, systemID string) *api.Stop_Reference { + if !stopID.Valid { + return nil + } + return r.Reference.Stop(stopID.String, systemID, stopName) +} diff --git a/internal/public/public.go b/internal/public/public.go index f2cfa595..745f8e90 100644 --- a/internal/public/public.go +++ b/internal/public/public.go @@ -25,7 +25,7 @@ type Server struct { // New creates a new `Server` that uses the provided pool to connect to the database. func New(pool *pgxpool.Pool, logger *slog.Logger, endpointOptions *endpoints.EndpointOptions) *Server { if endpointOptions == nil { - endpointOptions = &endpoints.EndpointOptions{MaxStopsPerRequest: 100} + endpointOptions = &endpoints.EndpointOptions{MaxStopsPerRequest: 100, MaxVehiclesPerRequest: 100} } return &Server{pool: pool, logger: logger, endpointOptions: endpointOptions} @@ -95,6 +95,14 @@ func (s *Server) GetAlert(ctx context.Context, req *api.GetAlertRequest) (*api.A return run(ctx, s, "GetAlert", endpoints.GetAlert, req) } +func (s *Server) ListVehicles(ctx context.Context, req *api.ListVehiclesRequest) (*api.ListVehiclesReply, error) { + return run(ctx, s, "ListVehicles", endpoints.ListVehicles, req) +} + +func (s *Server) GetVehicle(ctx context.Context, req *api.GetVehicleRequest) (*api.Vehicle, error) { + return run(ctx, s, "GetVehicle", endpoints.GetVehicle, req) +} + func run[S, T any](ctx context.Context, s *Server, methodName string, f func(context.Context, *endpoints.Context, S) (T, error), req S) (T, error) { startTime := time.Now() var t T diff --git a/internal/public/reference/reference.go b/internal/public/reference/reference.go index ccba56db..bd15abbf 100644 --- a/internal/public/reference/reference.go +++ b/internal/public/reference/reference.go @@ -136,10 +136,10 @@ func (h Generator) TransfersHref(systemID string) *string { return h.generateHref("systems", systemID, "transfers") } -func (h Generator) Vehicle(id string) *api.Vehicle_Reference { - // TODO: vehicle +func (h Generator) Vehicle(id string, systemID string) *api.Vehicle_Reference { return &api.Vehicle_Reference{ - Id: id, + Id: id, + Resource: h.generateResource("systems", systemID, "vehicles", id), } } diff --git a/internal/server/server.go b/internal/server/server.go index a23c6b2b..be8925f1 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -29,18 +29,19 @@ import ( ) type RunArgs struct { - PublicHTTPAddr string - PublicGrpcAddr string - AdminHTTPAddr string - AdminGrpcAddr string - PostgresConnStr string - MaxConnections int32 - EnableScheduler bool - EnablePublicMetrics bool - EnablePprof bool - ReadOnly bool - MaxStopsPerRequest int32 - LogLevel slog.Level + PublicHTTPAddr string + PublicGrpcAddr string + AdminHTTPAddr string + AdminGrpcAddr string + PostgresConnStr string + MaxConnections int32 + EnableScheduler bool + EnablePublicMetrics bool + EnablePprof bool + ReadOnly bool + MaxStopsPerRequest int32 + MaxVehiclesPerRequest int32 + LogLevel slog.Level } func Run(ctx context.Context, args RunArgs) error { diff --git a/internal/servicemaps/servicemaps.go b/internal/servicemaps/servicemaps.go index c82a5a87..036db189 100644 --- a/internal/servicemaps/servicemaps.go +++ b/internal/servicemaps/servicemaps.go @@ -363,7 +363,7 @@ func UpdateRealtimeMaps(ctx context.Context, querier db.Querier, logger *slog.Lo edges := buildRealtimeMapEdges(tripStopPks, stopPkToStationPk) mapAsStopPks, err := buildMap(edges) if err != nil { - logger.ErrorCtx(ctx, fmt.Sprintf("error building realtime map: %s", err)) + logger.DebugCtx(ctx, fmt.Sprintf("error building realtime map: %s", err)) continue } for _, smc := range configs[api.ServiceMapConfig_REALTIME] { diff --git a/internal/update/realtime/realtime.go b/internal/update/realtime/realtime.go index 286bab26..4bf77386 100644 --- a/internal/update/realtime/realtime.go +++ b/internal/update/realtime/realtime.go @@ -37,35 +37,51 @@ func Update(ctx context.Context, updateCtx common.UpdateContext, data *gtfs.Real if err := updateAlerts(ctx, updateCtx, data.Alerts); err != nil { return err } + if err := updateVehicles(ctx, updateCtx, data.Vehicles); err != nil { + return err + } return nil } func updateTrips(ctx context.Context, updateCtx common.UpdateContext, trips []gtfs.Trip) error { + var validTripEntities []gtfs.Trip + if updateCtx.FeedConfig != nil && + updateCtx.FeedConfig.GetGtfsRealtimeOptions().GetOnlyProcessFullEntities() { + for _, trip := range trips { + // Only insert trips that are in the feed. + if trip.IsEntityInMessage { + validTripEntities = append(validTripEntities, trip) + } + } + } else { + validTripEntities = trips + } + // ASSUMPTIONS: route ID is populated. If not, get it from the static data in an earlier phase - stopIDToPk, err := dbwrappers.MapStopIDToPkInSystem(ctx, updateCtx.Querier, updateCtx.SystemPk, stopIDsInTrips(trips)) + stopIDToPk, err := dbwrappers.MapStopIDToPkInSystem(ctx, updateCtx.Querier, updateCtx.SystemPk, stopIDsInTrips(validTripEntities)) if err != nil { return err } - stopHeadsignMatcher, err := NewStopHeadsignMatcher(ctx, updateCtx.Querier, stopIDToPk, trips) + stopHeadsignMatcher, err := NewStopHeadsignMatcher(ctx, updateCtx.Querier, stopIDToPk, validTripEntities) if err != nil { return err } - routeIDToPk, err := dbwrappers.MapRouteIDToPkInSystem(ctx, updateCtx.Querier, updateCtx.SystemPk, routeIDsInTrips(trips)) + routeIDToPk, err := dbwrappers.MapRouteIDToPkInSystem(ctx, updateCtx.Querier, updateCtx.SystemPk, routeIDsInTrips(validTripEntities)) if err != nil { return err } - existingTrips, err := dbwrappers.ListTripsForUpdate(ctx, updateCtx.Querier, common.MapValues(routeIDToPk)) + existingTrips, err := dbwrappers.ListTripsForUpdate(ctx, updateCtx.Querier, updateCtx.SystemPk, common.MapValues(routeIDToPk)) if err != nil { return err } - stagedUpdates := newStagedUpdates(trips) + stagedUpdates := newStagedUpdates(validTripEntities) seenUIDs := map[dbwrappers.TripUID]bool{} tripUIDToPk := map[dbwrappers.TripUID]int64{} tripUIDToTrip := map[dbwrappers.TripUID]*gtfs.Trip{} activeTripPks := []int64{} - for i := range trips { - trip := &trips[i] + for i := range validTripEntities { + trip := &validTripEntities[i] routePk, ok := routeIDToPk[trip.ID.RouteID] if !ok { continue @@ -161,6 +177,7 @@ func updateTrips(ctx context.Context, updateCtx common.UpdateContext, trips []gt if err := servicemaps.UpdateRealtimeMaps(ctx, updateCtx.Querier, updateCtx.Logger, updateCtx.SystemPk, common.MapKeys(routePksWithPathChanges)); err != nil { return err } + return nil } @@ -588,3 +605,184 @@ func convertOptionalTime(in *time.Time) pgtype.Timestamptz { Time: *in, } } + +func updateVehicles(ctx context.Context, updateCtx common.UpdateContext, vehicles []gtfs.Vehicle) error { + onlyProcessFullEntities := updateCtx.FeedConfig != nil && + updateCtx.FeedConfig.GetGtfsRealtimeOptions().GetOnlyProcessFullEntities() + var validVehicleEntities []gtfs.Vehicle + for _, vehicle := range vehicles { + // Only insert vehicles that are in the feed. + if onlyProcessFullEntities && !vehicle.IsEntityInMessage { + continue + } + + // Note: We can insert a vehicle with no ID if it has an associated + // trip, per the GTFS-realtime spec. For now, we'll just skip them. + if vehicle.GetID().ID == nil || *vehicle.GetID().ID == "" { + updateCtx.Logger.DebugCtx(ctx, "Vehicle has no ID or empty ID") + continue + } + + validVehicleEntities = append(validVehicleEntities, vehicle) + } + + if len(validVehicleEntities) == 0 { + return updateCtx.Querier.DeleteStaleVehicles(ctx, db.DeleteStaleVehiclesParams{ + FeedPk: updateCtx.FeedPk, + ActiveVehicleIds: []string{}, + }) + } + + var vehicleIDs []string + var stopIDs []string + var tripIDs []string + for i := range validVehicleEntities { + vehicle := &validVehicleEntities[i] + vehicleIDs = append(vehicleIDs, *vehicle.ID.ID) + if vehicle.StopID != nil { + stopIDs = append(stopIDs, *vehicle.StopID) + } + if vehicle.GetTrip().ID.ID != "" { + tripIDs = append(tripIDs, vehicle.GetTrip().ID.ID) + } + } + + // This statement also acquires a lock on the rows in the trip table associated + // with vehicles being inserted/updated. + tripIDToPk, err := dbwrappers.MapTripIDToPkInSystem(ctx, updateCtx.Querier, updateCtx.SystemPk, tripIDs) + if err != nil { + return err + } + + vehicleIDToPk, tripPkToVehicleID, err := dbwrappers.MapVehicleIDToPkandTripPkToVehicleID(ctx, updateCtx.Querier, updateCtx.SystemPk, vehicleIDs) + if err != nil { + return err + } + + // This statement does not currently lock the rows in the stop table associated + // with vehicles being inserted/updated. However, chanegs to the stop table should + // be rare, so conflicts should not be a major issue. + stopIDToPk, err := dbwrappers.MapStopIDToPkInSystem(ctx, updateCtx.Querier, updateCtx.SystemPk, stopIDs) + if err != nil { + return err + } + + err = updateCtx.Querier.DeleteStaleVehicles(ctx, db.DeleteStaleVehiclesParams{ + FeedPk: updateCtx.FeedPk, + ActiveVehicleIds: vehicleIDs, + }) + if err != nil { + return err + } + + insertedVehicleIDs := map[string]bool{} + insertedTripIDs := map[string]bool{} + for _, vehicle := range validVehicleEntities { + if _, ok := insertedVehicleIDs[*vehicle.ID.ID]; ok { + updateCtx.Logger.DebugCtx(ctx, "Duplicate vehicle ID in same update", *vehicle.ID.ID) + continue + } + insertedVehicleIDs[*vehicle.ID.ID] = true + + if _, ok := insertedTripIDs[vehicle.GetTrip().ID.ID]; ok { + updateCtx.Logger.DebugCtx(ctx, "Duplicate trip ID in same update", vehicle.GetTrip().ID.ID) + continue + } + + var tripPkOrNil *int64 = nil + if vehicle.GetTrip().ID.ID != "" { + // Check that the trip ID is not associated with multiple vehicle IDs. + if tripPk, ok := tripIDToPk[vehicle.GetTrip().ID.ID]; ok { + if vehicleIDForTripPk, ok := tripPkToVehicleID[tripPk]; ok { + if vehicleIDForTripPk != *vehicle.ID.ID { + updateCtx.Logger.DebugCtx(ctx, "Trip ID has multiple vehicle IDs", vehicle.GetTrip().ID.ID) + continue + } + } + } else { + // If trip ID points to a trip that doesn't exist, skip it. + updateCtx.Logger.DebugCtx(ctx, "Trip ID not found", vehicle.GetTrip().ID.ID) + continue + } + + tripPkOrNil = ptr(tripIDToPk[vehicle.GetTrip().ID.ID]) + insertedTripIDs[vehicle.GetTrip().ID.ID] = true + } + + var stopPkOrNil *int64 = nil + if vehicle.StopID != nil { + if stopID, ok := stopIDToPk[*vehicle.StopID]; ok { + stopPkOrNil = &stopID + } + } + + var latitude, longitude, bearing, speed *float32 = nil, nil, nil, nil + var odometer *float64 = nil + if vehicle.Position != nil { + latitude = vehicle.Position.Latitude + longitude = vehicle.Position.Longitude + bearing = vehicle.Position.Bearing + odometer = vehicle.Position.Odometer + speed = vehicle.Position.Speed + } + + if vehiclePk, vehicleExists := vehicleIDToPk[*vehicle.ID.ID]; vehicleExists { + // Update + err := updateCtx.Querier.UpdateVehicle(ctx, db.UpdateVehicleParams{ + Pk: vehiclePk, + TripPk: convert.NullInt64(tripPkOrNil), + FeedPk: updateCtx.FeedPk, + CurrentStopPk: convert.NullInt64(stopPkOrNil), + Label: convert.NullString(vehicle.ID.Label), + LicensePlate: convert.NullString(vehicle.ID.LicencePlate), + CurrentStatus: convert.NullVehicleCurrentStatus(vehicle.CurrentStatus), + Latitude: convert.Gps(latitude), + Longitude: convert.Gps(longitude), + Bearing: convert.NullFloat32(bearing), + Odometer: convert.NullFloat64(odometer), + Speed: convert.NullFloat32(speed), + CongestionLevel: convert.CongestionLevel(vehicle.CongestionLevel), + UpdatedAt: convert.NullTime(vehicle.Timestamp), + CurrentStopSequence: convert.NullUInt32ToSigned(vehicle.CurrentStopSequence), + OccupancyStatus: convert.NullOccupancyStatus(vehicle.OccupancyStatus), + OccupancyPercentage: convert.NullUInt32ToSigned(vehicle.OccupancyPercentage), + }) + + if err != nil { + return err + } + } else { + // Insert + err := updateCtx.Querier.InsertVehicle(ctx, db.InsertVehicleParams{ + ID: convert.NullString(vehicle.ID.ID), + SystemPk: updateCtx.SystemPk, + TripPk: convert.NullInt64(tripPkOrNil), + FeedPk: updateCtx.FeedPk, + CurrentStopPk: convert.NullInt64(stopPkOrNil), + Label: convert.NullString(vehicle.ID.Label), + LicensePlate: convert.NullString(vehicle.ID.LicencePlate), + CurrentStatus: convert.NullVehicleCurrentStatus(vehicle.CurrentStatus), + Latitude: convert.Gps(latitude), + Longitude: convert.Gps(longitude), + Bearing: convert.NullFloat32(bearing), + Odometer: convert.NullFloat64(odometer), + Speed: convert.NullFloat32(speed), + CongestionLevel: convert.CongestionLevel(vehicle.CongestionLevel), + UpdatedAt: convert.NullTime(vehicle.Timestamp), + CurrentStopSequence: convert.NullUInt32ToSigned(vehicle.CurrentStopSequence), + OccupancyStatus: convert.NullOccupancyStatus(vehicle.OccupancyStatus), + OccupancyPercentage: convert.NullUInt32ToSigned(vehicle.OccupancyPercentage), + }) + + if err != nil { + return err + } + } + } + + return nil +} + +func ptr[T any](t T) *T { + return &t +} diff --git a/internal/update/realtime/realtime_test.go b/internal/update/realtime/realtime_test.go index b3361cc6..ebbb3c9b 100644 --- a/internal/update/realtime/realtime_test.go +++ b/internal/update/realtime/realtime_test.go @@ -6,6 +6,7 @@ import ( "time" "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgtype" "github.com/jamespfennell/gtfs" @@ -14,15 +15,19 @@ import ( "github.com/jamespfennell/transiter/internal/gen/api" "github.com/jamespfennell/transiter/internal/gen/db" "github.com/jamespfennell/transiter/internal/update/common" + "golang.org/x/exp/slog" ) const ( - routeID1 = "routeID1" - stopID1 = "stopID1" - stopID2 = "stopID2" - stopID3 = "stopID3" - stopID4 = "stopID4" - tripID1 = "tripID1" + systemID = "systemID1" + routeID1 = "routeID1" + stopID1 = "stopID1" + stopID2 = "stopID2" + stopID3 = "stopID3" + stopID4 = "stopID4" + tripID1 = "tripID1" + vehicleID1 = "vehicleID1" + vehicleID2 = "vehicleID2" ) func TestUpdateTrips(t *testing.T) { @@ -160,7 +165,7 @@ func TestUpdateTrips(t *testing.T) { } { t.Run(tc.name, func(t *testing.T) { querier := dbtesting.NewQuerier(t) - system := querier.NewSystem("system") + system := querier.NewSystem(systemID) stopPkToID := map[int64]string{} for _, stopID := range []string{stopID1, stopID2, stopID3, stopID4} { stopPkToID[system.NewStop(stopID).Pk] = stopID @@ -182,6 +187,7 @@ func TestUpdateTrips(t *testing.T) { FeedConfig: &api.FeedConfig{ GtfsRealtimeOptions: tc.gtfsRealTimeOptions, }, + Logger: slog.Default(), } for i, tripVersion := range tc.tripVersions { @@ -204,12 +210,520 @@ func TestUpdateTrips(t *testing.T) { } } +func TestUpdateVehicles(t *testing.T) { + for _, tc := range []struct { + name string + vehicleGroups [][]*gtfs.Vehicle + wantVehicleGroups [][]*Vehicle + tripVersions []*gtfs.Trip + }{ + { + name: "simple case", + vehicleGroups: [][]*gtfs.Vehicle{ + { + { + ID: >fs.VehicleID{ + ID: ptr(vehicleID1), + }, + IsEntityInMessage: true, + }, + }, + }, + wantVehicleGroups: [][]*Vehicle{ + { + wantVehicle(ptr(vehicleID1), systemID, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil), + }, + }, + }, + { + name: "trip with no id", + vehicleGroups: [][]*gtfs.Vehicle{ + { + { + ID: >fs.VehicleID{}, + IsEntityInMessage: true, + }, + }, + }, + wantVehicleGroups: [][]*Vehicle{ + {}, + }, + }, + { + name: "entity not in message", + vehicleGroups: [][]*gtfs.Vehicle{ + { + { + ID: >fs.VehicleID{ + ID: ptr(vehicleID1), + }, + }, + }, + }, + wantVehicleGroups: [][]*Vehicle{ + {}, + }, + }, + { + name: "lots of fields", + vehicleGroups: [][]*gtfs.Vehicle{ + { + { + ID: >fs.VehicleID{ + ID: ptr(vehicleID1), + Label: ptr("label"), + LicencePlate: ptr("licencePlate"), + }, + Position: >fs.Position{ + Latitude: ptr(float32(1.0)), + Longitude: ptr(float32(2.0)), + Bearing: ptr(float32(3.0)), + Odometer: ptr(4.0), + Speed: ptr(float32(5.0)), + }, + // STOPPED_AT + CurrentStatus: ptr(gtfs.CurrentStatus(1)), + Timestamp: ptr(mkTime(6)), + // RUNNING_SMOOTHLY + CongestionLevel: gtfs.CongestionLevel(1), + // MANY_SEATS_AVAILABLE + OccupancyStatus: ptr(gtfs.OccupancyStatus(1)), + OccupancyPercentage: ptr(uint32(8)), + IsEntityInMessage: true, + }, + }, + }, + wantVehicleGroups: [][]*Vehicle{ + { + wantVehicle( + ptr(vehicleID1), systemID, nil, + ptr("label"), ptr("licencePlate"), + ptr(float32(1.0)), ptr(float32(2.0)), ptr(float32(3.0)), ptr(4.0), ptr(float32(5.0)), + ptr(gtfs.CongestionLevel(1)), + ptr(mkTime(6)), + nil, + ptr(gtfs.OccupancyStatus(1)), + ptr(gtfs.CurrentStatus(1)), + nil, + ptr(uint32(8))), + }, + }, + }, + { + name: "associated trip", + vehicleGroups: [][]*gtfs.Vehicle{ + { + { + ID: >fs.VehicleID{ + ID: ptr(vehicleID1), + }, + Trip: >fs.Trip{ + ID: gtfs.TripID{ + ID: tripID1, + }, + }, + IsEntityInMessage: true, + }, + }, + }, + wantVehicleGroups: [][]*Vehicle{ + { + wantVehicle(ptr(vehicleID1), systemID, ptr(tripID1), + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil), + }, + }, + tripVersions: []*gtfs.Trip{ + gtfsTrip(tripID1, routeID1, gtfs.DirectionIDTrue, []gtfs.StopTimeUpdate{}), + }, + }, + { + name: "duplicate trips, same update", + vehicleGroups: [][]*gtfs.Vehicle{ + { + { + ID: >fs.VehicleID{ + ID: ptr(vehicleID1), + }, + Trip: >fs.Trip{ + ID: gtfs.TripID{ + ID: tripID1, + }, + }, + IsEntityInMessage: true, + }, + { + ID: >fs.VehicleID{ + ID: ptr(vehicleID2), + }, + Trip: >fs.Trip{ + ID: gtfs.TripID{ + ID: tripID1, + }, + }, + IsEntityInMessage: true, + }, + }, + }, + wantVehicleGroups: [][]*Vehicle{ + { + wantVehicle(ptr(vehicleID1), systemID, ptr(tripID1), + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil), + }, + }, + tripVersions: []*gtfs.Trip{ + gtfsTrip(tripID1, routeID1, gtfs.DirectionIDTrue, []gtfs.StopTimeUpdate{}), + }, + }, + { + name: "trip changes vehicles across updates", + vehicleGroups: [][]*gtfs.Vehicle{ + { + { + ID: >fs.VehicleID{ + ID: ptr(vehicleID1), + }, + Trip: >fs.Trip{ + ID: gtfs.TripID{ + ID: tripID1, + }, + }, + IsEntityInMessage: true, + }, + }, + { + { + ID: >fs.VehicleID{ + ID: ptr(vehicleID2), + }, + Trip: >fs.Trip{ + ID: gtfs.TripID{ + ID: tripID1, + }, + }, + IsEntityInMessage: true, + }, + }, + }, + wantVehicleGroups: [][]*Vehicle{ + { + wantVehicle(ptr(vehicleID1), systemID, ptr(tripID1), + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil), + }, + { + wantVehicle(ptr(vehicleID2), systemID, ptr(tripID1), + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil), + }, + }, + tripVersions: []*gtfs.Trip{ + gtfsTrip(tripID1, routeID1, gtfs.DirectionIDTrue, []gtfs.StopTimeUpdate{}), + }, + }, + { + name: "duplicate trips, different updates", + vehicleGroups: [][]*gtfs.Vehicle{ + { + { + ID: >fs.VehicleID{ + ID: ptr(vehicleID1), + }, + Trip: >fs.Trip{ + ID: gtfs.TripID{ + ID: tripID1, + }, + }, + IsEntityInMessage: true, + }, + }, + { + { + ID: >fs.VehicleID{ + ID: ptr(vehicleID1), + }, + Trip: >fs.Trip{ + ID: gtfs.TripID{ + ID: tripID1, + }, + }, + IsEntityInMessage: true, + }, + { + ID: >fs.VehicleID{ + ID: ptr(vehicleID2), + }, + Trip: >fs.Trip{ + ID: gtfs.TripID{ + ID: tripID1, + }, + }, + IsEntityInMessage: true, + }, + }, + }, + wantVehicleGroups: [][]*Vehicle{ + { + wantVehicle(ptr(vehicleID1), systemID, ptr(tripID1), + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil), + }, + { + // If an existing vehicle and incoming vehicle both have same trip ID, we + // keep the exsiting vehicle and ignore the incoming vehicle. + wantVehicle(ptr(vehicleID1), systemID, ptr(tripID1), + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil), + }, + }, + tripVersions: []*gtfs.Trip{ + gtfsTrip(tripID1, routeID1, gtfs.DirectionIDTrue, []gtfs.StopTimeUpdate{}), + }, + }, + { + name: "duplicate vehicle ids", + vehicleGroups: [][]*gtfs.Vehicle{ + { + { + ID: >fs.VehicleID{ + ID: ptr(vehicleID1), + }, + IsEntityInMessage: true, + }, + { + ID: >fs.VehicleID{ + ID: ptr(vehicleID1), + }, + IsEntityInMessage: true, + }, + }, + }, + wantVehicleGroups: [][]*Vehicle{ + { + wantVehicle(ptr(vehicleID1), systemID, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil), + }, + }, + tripVersions: []*gtfs.Trip{ + gtfsTrip(tripID1, routeID1, gtfs.DirectionIDTrue, []gtfs.StopTimeUpdate{}), + }, + }, + { + name: "associated trip and stop", + vehicleGroups: [][]*gtfs.Vehicle{ + { + { + ID: >fs.VehicleID{ + ID: ptr(vehicleID1), + }, + Trip: >fs.Trip{ + ID: gtfs.TripID{ + ID: tripID1, + }, + }, + CurrentStopSequence: ptr(uint32(0)), + StopID: ptr(stopID1), + IsEntityInMessage: true, + }, + }, + }, + wantVehicleGroups: [][]*Vehicle{ + { + wantVehicle(ptr(vehicleID1), systemID, ptr(tripID1), + nil, nil, nil, nil, nil, nil, nil, nil, nil, ptr(int32(0)), nil, nil, ptr(stopID1), nil), + }, + }, + tripVersions: []*gtfs.Trip{ + gtfsTrip(tripID1, routeID1, gtfs.DirectionIDTrue, []gtfs.StopTimeUpdate{ + gtfsStu(gStopID(stopID1), gDepTime(5)), + gtfsStu(gStopID(stopID2), gArrTime(10), gDepTime(15)), + }), + }, + }, { + name: "vehicle update", + vehicleGroups: [][]*gtfs.Vehicle{ + { + { + ID: >fs.VehicleID{ + ID: ptr(vehicleID1), + }, + Position: >fs.Position{ + Latitude: ptr(float32(1.0)), + Longitude: ptr(float32(2.0)), + Bearing: ptr(float32(3.0)), + Odometer: ptr(4.0), + Speed: ptr(float32(5.0)), + }, + IsEntityInMessage: true, + }, + }, + { + { + ID: >fs.VehicleID{ + ID: ptr(vehicleID1), + }, + Position: >fs.Position{ + Latitude: ptr(float32(2.0)), + Longitude: ptr(float32(3.0)), + Bearing: ptr(float32(4.0)), + Odometer: ptr(5.0), + Speed: ptr(float32(6.0)), + }, + IsEntityInMessage: true, + }, + }, + }, + wantVehicleGroups: [][]*Vehicle{ + { + wantVehicle( + ptr(vehicleID1), systemID, nil, + nil, nil, + ptr(float32(1.0)), ptr(float32(2.0)), ptr(float32(3.0)), ptr(4.0), ptr(float32(5.0)), + nil, + nil, + nil, + nil, + nil, + nil, + nil), + }, + { + wantVehicle( + ptr(vehicleID1), systemID, nil, + nil, nil, + ptr(float32(2.0)), ptr(float32(3.0)), ptr(float32(4.0)), ptr(5.0), ptr(float32(6.0)), + nil, + nil, + nil, + nil, + nil, + nil, + nil), + }, + }, + }, + { + name: "stale vehicle deleted", + vehicleGroups: [][]*gtfs.Vehicle{ + { + { + ID: >fs.VehicleID{ + ID: ptr(vehicleID1), + }, + IsEntityInMessage: true, + }, + { + ID: >fs.VehicleID{ + ID: ptr(vehicleID2), + }, + IsEntityInMessage: true, + }, + }, + { + { + ID: >fs.VehicleID{ + ID: ptr(vehicleID2), + }, + IsEntityInMessage: true, + }, + }, + }, + wantVehicleGroups: [][]*Vehicle{ + { + wantVehicle(ptr(vehicleID1), systemID, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil), + wantVehicle(ptr(vehicleID2), systemID, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil), + }, + { + wantVehicle(ptr(vehicleID2), systemID, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil), + }, + }, + }, + } { + t.Run(tc.name, func(t *testing.T) { + querier := dbtesting.NewQuerier(t) + system := querier.NewSystem(systemID) + stopPkToID := map[int64]string{} + for _, stopID := range []string{stopID1, stopID2, stopID3, stopID4} { + stopPkToID[system.NewStop(stopID).Pk] = stopID + } + for _, routeID := range []string{routeID1} { + system.NewRoute(routeID) + } + tripsFeed := system.NewFeed("trips") + vehiclesFeed := system.NewFeed("vehicles") + + ctx := context.Background() + updateCtx := common.UpdateContext{ + Querier: querier, + SystemPk: system.Data.Pk, + Logger: slog.Default(), + } + + for i, tripVersion := range tc.tripVersions { + updateCtx.FeedPk = tripsFeed.Data.Pk + var r gtfs.Realtime + if tripVersion != nil { + r.Trips = append(r.Trips, *tripVersion) + } + err := Update(ctx, updateCtx, &r) + if err != nil { + t.Fatalf("Update(trip version %d) got = %v, want = ", err, i) + } + } + + systemPkToID := map[int64]string{} + systemPkToID[system.Data.Pk] = systemID + + if len(tc.vehicleGroups) != len(tc.wantVehicleGroups) { + t.Fatalf("len(vehicleGroups) != len(wantVehicleGroups)") + } + + updateCtx.FeedPk = vehiclesFeed.Data.Pk + updateCtx.FeedConfig = &api.FeedConfig{ + GtfsRealtimeOptions: &api.GtfsRealtimeOptions{ + OnlyProcessFullEntities: true, + }, + } + for i := range tc.vehicleGroups { + vehicles := tc.vehicleGroups[i] + wantVehicles := tc.wantVehicleGroups[i] + + var r gtfs.Realtime + for _, vehicle := range vehicles { + r.Vehicles = append(r.Vehicles, *vehicle) + } + + err := Update(ctx, updateCtx, &r) + if err != nil { + t.Fatalf("Update(vehicle %d) got = %v, want = ", err, i) + } + + dbVehicles := readVehiclesFromDB(ctx, t, querier, system.Data.Pk, systemPkToID) + + opt := cmp.Options{ + cmpopts.IgnoreUnexported(pgtype.Numeric{}), + cmp.Comparer(compareNumerics), + } + if diff := cmp.Diff(dbVehicles, wantVehicles, opt); diff != "" { + t.Errorf("got = %v, want = %v, diff = %s", vehicles, tc.vehicleGroups, diff) + } + } + }) + } +} + type Trip struct { RouteID string - DBFields db.Trip + DBFields db.GetTripRow StopTimes []StopTime } +type Vehicle struct { + SystemID string + TripID *string + CurrentStopID *string + DBFields db.GetVehicleRow +} + func readTripFromDB(ctx context.Context, t *testing.T, querier db.Querier, routeIDToPk map[string]int64, stopPkToID map[int64]string) *Trip { dbTrip, err := querier.GetTrip(ctx, db.GetTripParams{ RoutePk: routeIDToPk[routeID1], @@ -242,10 +756,71 @@ func readTripFromDB(ctx context.Context, t *testing.T, querier db.Querier, route } } +func readVehiclesFromDB( + ctx context.Context, + t *testing.T, querier db.Querier, + systemPk int64, + systemPkToID map[int64]string) []*Vehicle { + dbVehicles, err := querier.ListVehicles(ctx, db.ListVehiclesParams{ + SystemPk: systemPk, + NumVehicles: 100, + FirstVehicleID: convert.NullString(ptr("")), + }) + if err == pgx.ErrNoRows { + return nil + } + if err != nil { + t.Fatalf("ListVehicles(systemPk=%d) err got = %v, want = ", systemPk, err) + } + + vehicles := make([]*Vehicle, 0, len(dbVehicles)) + + for _, dbVehicle := range dbVehicles { + systemID, ok := systemPkToID[dbVehicle.SystemPk] + if !ok { + t.Fatalf("systemPkToID[%d] not found", systemPk) + } + + var tripID *string = nil + if dbVehicle.TripID.Valid { + tripID = &dbVehicle.TripID.String + } + + var currentStopID *string = nil + if dbVehicle.StopID.Valid { + currentStopID = &dbVehicle.StopID.String + } + + vehicles = append(vehicles, &Vehicle{ + SystemID: systemID, + TripID: tripID, + CurrentStopID: currentStopID, + DBFields: db.GetVehicleRow{ + ID: dbVehicle.ID, + Label: dbVehicle.Label, + LicensePlate: dbVehicle.LicensePlate, + Latitude: dbVehicle.Latitude, + Longitude: dbVehicle.Longitude, + Bearing: dbVehicle.Bearing, + Odometer: dbVehicle.Odometer, + Speed: dbVehicle.Speed, + CongestionLevel: dbVehicle.CongestionLevel, + UpdatedAt: dbVehicle.UpdatedAt, + OccupancyStatus: dbVehicle.OccupancyStatus, + CurrentStatus: dbVehicle.CurrentStatus, + CurrentStopSequence: dbVehicle.CurrentStopSequence, + OccupancyPercentage: dbVehicle.OccupancyPercentage, + }, + }) + } + + return vehicles +} + func wantTrip(tripID, routeID string, directionID bool, sts []StopTime) *Trip { return &Trip{ RouteID: routeID, - DBFields: db.Trip{ + DBFields: db.GetTripRow{ ID: tripID, DirectionID: convert.NullBool(&directionID), }, @@ -253,6 +828,43 @@ func wantTrip(tripID, routeID string, directionID bool, sts []StopTime) *Trip { } } +func wantVehicle( + vehicleID *string, + systemID string, + tripID, label, licensePlate *string, + latitude, longitude, bearing *float32, + odometer *float64, + speed *float32, + congestionLevel *gtfs.CongestionLevel, + updatedAt *time.Time, + currentStopSequence *int32, + occupancyStatus *gtfs.OccupancyStatus, + currentStatus *gtfs.CurrentStatus, + currentStopID *string, + occupancyPercentage *uint32) *Vehicle { + return &Vehicle{ + SystemID: systemID, + TripID: tripID, + CurrentStopID: currentStopID, + DBFields: db.GetVehicleRow{ + ID: convert.NullString(vehicleID), + Label: convert.NullString(label), + LicensePlate: convert.NullString(licensePlate), + CurrentStatus: convert.NullVehicleCurrentStatus(currentStatus), + Latitude: convert.Gps(latitude), + Longitude: convert.Gps(longitude), + Bearing: convert.NullFloat32(bearing), + Odometer: convert.NullFloat64(odometer), + Speed: convert.NullFloat32(speed), + CongestionLevel: convert.NullCongestionLevel(congestionLevel), + UpdatedAt: convert.NullTime(updatedAt), + CurrentStopSequence: convert.NullInt32(currentStopSequence), + OccupancyStatus: convert.NullOccupancyStatus(occupancyStatus), + OccupancyPercentage: convert.NullUInt32ToSigned(occupancyPercentage), + }, + } +} + type StopTime struct { StopID string DBFields db.ListStopsTimesForTripRow @@ -369,3 +981,35 @@ func gtfsTrip(tripID, routeID string, directionID gtfs.DirectionID, stus []gtfs. StopTimeUpdates: stus, } } + +func compareNumerics(x, y pgtype.Numeric) bool { + if !x.Valid && !y.Valid { + return true + } + + if x.NaN && y.NaN { + return true + } + + if x.NaN != y.NaN { + return false + } + + if x.Valid != y.Valid { + return false + } + + if x.Int == nil && y.Int == nil { + return x.Exp == y.Exp + } + + if x.Int == nil || y.Int == nil { + return false + } + + if x.Int.Cmp(y.Int) != 0 { + return false + } + + return x.Exp == y.Exp +} diff --git a/systems/us-ny-nycbus.yaml b/systems/us-ny-nycbus.yaml index 42ff40b1..4ab7893e 100644 --- a/systems/us-ny-nycbus.yaml +++ b/systems/us-ny-nycbus.yaml @@ -21,15 +21,23 @@ feeds: parser: GTFS_STATIC url: "http://web.mta.info/developers/data/nyct/bus/google_transit_staten_island.zip" - - id: trips + - id: gtfsstatic_bus_company + parser: GTFS_STATIC + url: "http://web.mta.info/developers/data/busco/google_transit.zip" + - id: trips parser: GTFS_REALTIME - gtfsRealtimeOptions: - extension: NYCT_BUS_TRIPS - reassignStopSequences: true - url: "https://gtfsrt.prod.obanyc.com/tripUpdates?key={{ .Args.mta_bus_api_key }}" + gtfsRealtimeOptions: + reassignStopSequences: true + onlyProcessFullEntities: true - id: "alerts" parser: GTFS_REALTIME url: "http://gtfsrt.prod.obanyc.com/alerts?key={{ .Args.mta_bus_api_key }}" + + - id: "vehicles" + parser: GTFS_REALTIME + url: "http://gtfsrt.prod.obanyc.com/vehiclePositions?key={{ .Args.mta_bus_api_key }}" + gtfsRealtimeOptions: + onlyProcessFullEntities: true diff --git a/tests/endtoend/Dockerfile b/tests/endtoend/Dockerfile index c0857ed0..92cd7de6 100644 --- a/tests/endtoend/Dockerfile +++ b/tests/endtoend/Dockerfile @@ -15,5 +15,6 @@ COPY test_installsystem.py . COPY test_periodicupdate.py . COPY test_servicemaps.py . COPY test_trips.py . +COPY test_vehicles.py . ENTRYPOINT ["pytest", "-n", "4"] diff --git a/tests/endtoend/conftest.py b/tests/endtoend/conftest.py index 8a012855..4bb02bcb 100644 --- a/tests/endtoend/conftest.py +++ b/tests/endtoend/conftest.py @@ -137,6 +137,8 @@ def delete(): parser: GTFS_REALTIME schedulingPolicy: PERIODIC updatePeriodS: {realtime_periodic_update_period} + gtfsRealtimeOptions: + onlyProcessFullEntities: {only_process_full_entities} """ @@ -148,7 +150,7 @@ def install_system_1( source_server_host_within_transiter, install_system, ): - def install(system_id, realtime_periodic_update_period="3600000"): + def install(system_id, realtime_periodic_update_period="3600000", only_process_full_entities = "false"): static_feed_url = source_server.create("", "/" + system_id + "/gtfs-static.zip") source_server.put(static_feed_url, get_zip("gtfsstatic")) realtime_feed_url = source_server.create( @@ -161,6 +163,7 @@ def install(system_id, realtime_periodic_update_period="3600000"): + "/" + realtime_feed_url, realtime_periodic_update_period=realtime_periodic_update_period, + only_process_full_entities=only_process_full_entities, ) install_system(system_id, system_config) diff --git a/tests/endtoend/test_vehicles.py b/tests/endtoend/test_vehicles.py new file mode 100644 index 00000000..ed1d4d67 --- /dev/null +++ b/tests/endtoend/test_vehicles.py @@ -0,0 +1,294 @@ +import pytest +import requests +from . import gtfs_realtime_pb2 as gtfs +from haversine import haversine + +VEHICLE_ID_1 = "vehicle_id_1" +VEHICLE_ID_2 = "vehicle_id_2" +VEHICLE_ID_3 = "vehicle_id_3" +VEHICLE_IDS = {VEHICLE_ID_1, VEHICLE_ID_2, VEHICLE_ID_3} +VEHICLE_1_LAT = 40.7527 +VEHICLE_1_LON = -73.9772 +TRIP_ID_1 = "trip_id_1" +TRIP_ID_2 = "trip_id_2" +TRIP_ID_3 = "trip_id_3" +ROUTE_ID = "A" +FIRST_STOP_ID = "1AS" + + +@pytest.mark.parametrize( + "stop_id_to_time", + [{ + FIRST_STOP_ID: 300, + "1BS": 800, + "1CS": 850, + }], +) +@pytest.mark.parametrize( + "vehicles", + [ + { + VEHICLE_ID_1: { + "trip_id": TRIP_ID_1, + "lat": VEHICLE_1_LAT, + "lon": VEHICLE_1_LON, + }, + VEHICLE_ID_2: { + "trip_id": TRIP_ID_2, + "lat": 50, + "lon": -50, + }, + VEHICLE_ID_3: { + "trip_id": TRIP_ID_3, + "lat": 150, + "lon": -150, + }, + }, + ], +) +class TestVehicles: + + def test_vehicle_view(self, install_system_1, system_id, transiter_host, + source_server, stop_id_to_time, vehicles): + __, realtime_feed_url = install_system_1( + system_id, only_process_full_entities="true") + + source_server.put( + realtime_feed_url, + build_gtfs_rt_message(stop_id_to_time, + vehicles).SerializeToString(), + ) + response = requests.post( + f"{transiter_host}/systems/{system_id}/feeds/GtfsRealtimeFeed" + ).json() + print(response) + + # List vehicles + response = requests.get( + f"{transiter_host}/systems/{system_id}/vehicles").json() + print(response) + + resp_vehicles = response["vehicles"] + compare_vehicles_to_resp(vehicles, resp_vehicles) + + # List vehicles (pagination) + paginated_vehicles = [] + next_id = None + num_pages = 0 + while len(paginated_vehicles) < len(vehicles): + query_params = { + "limit": 2, + } + if next_id: + query_params["first_id"] = next_id + response = requests.get( + f"{transiter_host}/systems/{system_id}/vehicles", + params=query_params).json() + assert len(response["vehicles"]) <= 2 + paginated_vehicles.extend(response["vehicles"]) + num_pages += 1 + + if "nextId" not in response: + break + next_id = response["nextId"] + + compare_vehicles_to_resp(vehicles, paginated_vehicles) + assert num_pages == 2 + + # List vehicles by ids + query_params = { + "only_return_specified_ids": True, + "id[]": [VEHICLE_ID_2, VEHICLE_ID_3], + } + response = requests.get( + f"{transiter_host}/systems/{system_id}/vehicles", + params=query_params).json() + print(response) + assert {VEHICLE_ID_2, + VEHICLE_ID_3} == set(vehicle["id"] + for vehicle in response["vehicles"]) + compare_vehicles_to_resp(vehicles, response["vehicles"], { + VEHICLE_ID_2, + VEHICLE_ID_3, + }) + + # Get vehicle + for vehicle_id, vehicle in vehicles.items(): + resp_vehicle = requests.get( + f"{transiter_host}/systems/{system_id}/vehicles/{vehicle_id}" + ).json() + compare_vehicle_to_resp({ + **vehicle, "id": vehicle_id + }, resp_vehicle) + + # Geolocation + relative_lat_lon = (40.7559, -73.9871) + vehicle_1_lat_lon = (VEHICLE_1_LAT, VEHICLE_1_LON) + + dist_km = haversine(relative_lat_lon, vehicle_1_lat_lon) + assert dist_km > 0.9 and dist_km < 1.0 + + query_params = { + "search_mode": "DISTANCE", + "latitude": relative_lat_lon[0], + "longitude": relative_lat_lon[1], + "max_distance": 1.0, + } + + response = requests.get( + f"{transiter_host}/systems/{system_id}/vehicles", + params=query_params).json() + print(response) + vehicles_geo = response["vehicles"] + + # Only 1st vehicle is within 1km of the relative location + assert 1 == len(vehicles_geo) + assert VEHICLE_ID_1 == vehicles_geo[0]["id"] + + query_params_closer = {**query_params, "max_distance": 0.5} + response = requests.get( + f"{transiter_host}/systems/{system_id}/vehicles", + params=query_params_closer).json() + + # No vehicles within 0.5km of relative location + assert 0 == len(response["vehicles"]) + + query_params_all_of_earth = {**query_params, "max_distance": 40075} + response = requests.get( + f"{transiter_host}/systems/{system_id}/vehicles", + params=query_params_all_of_earth).json() + + # All vehicles returned + compare_vehicles_to_resp(vehicles, response["vehicles"]) + + def test_trip_view(self, install_system_1, system_id, transiter_host, + source_server, stop_id_to_time, vehicles): + __, realtime_feed_url = install_system_1( + system_id, only_process_full_entities="true") + + source_server.put( + realtime_feed_url, + build_gtfs_rt_message(stop_id_to_time, + vehicles).SerializeToString(), + ) + response = requests.post( + f"{transiter_host}/systems/{system_id}/feeds/GtfsRealtimeFeed" + ).json() + print(response) + + response = requests.get( + f"{transiter_host}/systems/{system_id}/routes/{ROUTE_ID}/trips/{TRIP_ID_1}" + ).json() + print(response) + + assert response["id"] == TRIP_ID_1 + assert response["vehicle"]["id"] == VEHICLE_ID_1 + + def test_stop_view(self, install_system_1, system_id, transiter_host, + source_server, stop_id_to_time, vehicles): + __, realtime_feed_url = install_system_1( + system_id, only_process_full_entities="true") + + source_server.put( + realtime_feed_url, + build_gtfs_rt_message(stop_id_to_time, + vehicles).SerializeToString(), + ) + response = requests.post( + f"{transiter_host}/systems/{system_id}/feeds/GtfsRealtimeFeed" + ).json() + print(response) + + response = requests.get( + f"{transiter_host}/systems/{system_id}/stops/{FIRST_STOP_ID}" + ).json() + print(response) + + stop_times = response["stopTimes"] + assert len(stop_times) == 1 + + stop_time = stop_times[0] + assert stop_time["trip"]["id"] == TRIP_ID_1 + assert stop_time["trip"]["vehicle"]["id"] == VEHICLE_ID_1 + + +def compare_vehicles_to_resp(vehicles, resp_vehicles, expected_ids=None): + if expected_ids is None: + expected_ids = set(vehicles.keys()) + assert len(expected_ids) == len(resp_vehicles) + + for vehicle_id in expected_ids: + vehicle = vehicles[vehicle_id] + resp_vehicles_with_id = [ + v for v in resp_vehicles if v["id"] == vehicle_id + ] + assert len(resp_vehicles_with_id) == 1 + + resp_vehicle = resp_vehicles_with_id[0] + compare_vehicle_to_resp({**vehicle, "id": vehicle_id}, resp_vehicle) + + +def compare_vehicle_to_resp(vehicle, resp_vehicle): + assert resp_vehicle["id"] == vehicle["id"] + assert resp_vehicle["latitude"] == vehicle["lat"] + assert resp_vehicle["longitude"] == vehicle["lon"] + assert resp_vehicle["trip"]["id"] == vehicle["trip_id"] + assert resp_vehicle["trip"]["route"]["id"] == ROUTE_ID + + +def build_gtfs_rt_message(stop_id_to_time, vehicles): + vehicles_entities = [ + gtfs.FeedEntity( + id=f"vehicle_{idx}", + vehicle=gtfs.VehiclePosition( + vehicle=gtfs.VehicleDescriptor(id=vehicle_id), + trip=gtfs.TripDescriptor(trip_id=vehicle["trip_id"]), + position=gtfs.Position( + latitude=vehicle["lat"], + longitude=vehicle["lon"], + ), + )) for idx, (vehicle_id, vehicle) in enumerate(vehicles.items()) + ] + + return gtfs.FeedMessage( + header=gtfs.FeedHeader(gtfs_realtime_version="2.0", timestamp=0), + entity=vehicles_entities + [ + gtfs.FeedEntity( + id="trip_update_1", + trip_update=gtfs.TripUpdate( + vehicle=gtfs.VehicleDescriptor(id=VEHICLE_ID_1), + trip=gtfs.TripDescriptor(trip_id=TRIP_ID_1, + route_id=ROUTE_ID, + direction_id=True), + stop_time_update=[ + gtfs.TripUpdate.StopTimeUpdate( + arrival=gtfs.TripUpdate.StopTimeEvent(time=time), + departure=gtfs.TripUpdate.StopTimeEvent(time=time + + 15), + stop_id=stop_id, + stop_sequence=stop_sequence + 25, + ) for stop_sequence, + (stop_id, time) in enumerate(stop_id_to_time.items()) + ], + ), + ), + gtfs.FeedEntity( + id="trip_update_2", + trip_update=gtfs.TripUpdate( + vehicle=gtfs.VehicleDescriptor(id=VEHICLE_ID_2), + trip=gtfs.TripDescriptor(trip_id=TRIP_ID_2, + route_id=ROUTE_ID, + direction_id=True), + ), + ), + gtfs.FeedEntity( + id="trip_update_3", + trip_update=gtfs.TripUpdate( + vehicle=gtfs.VehicleDescriptor(id=VEHICLE_ID_3), + trip=gtfs.TripDescriptor(trip_id=TRIP_ID_3, + route_id=ROUTE_ID, + direction_id=True), + ), + ) + ], + ) diff --git a/transiter.go b/transiter.go index 622f863e..aa11613a 100644 --- a/transiter.go +++ b/transiter.go @@ -190,6 +190,11 @@ func main() { Usage: "Maximum number of stops that will be returned in a single list stops request. Specifying a value <= 0 will disable the limit.", Value: 100, }, + &cli.Int64Flag{ + Name: "max-vehicles-per-request", + Usage: "Maximum number of vehicles that will be returned in a single list vehicles request. Specifying a value <= 0 will disable the limit.", + Value: 100, + }, &cli.StringFlag{ Name: "log-level", Usage: "Log level, either debug, info, warning or error", @@ -202,18 +207,19 @@ func main() { return err } args := server.RunArgs{ - PublicHTTPAddr: c.String("public-http-addr"), - PublicGrpcAddr: c.String("public-grpc-addr"), - AdminHTTPAddr: c.String("admin-http-addr"), - AdminGrpcAddr: c.String("admin-grpc-addr"), - PostgresConnStr: c.String("postgres-connection-string"), - MaxConnections: int32(c.Int64("max-connections")), - EnableScheduler: c.Bool("enable-scheduler"), - EnablePublicMetrics: c.Bool("enable-public-metrics"), - ReadOnly: c.Bool("read-only"), - EnablePprof: c.Bool("enable-pprof"), - MaxStopsPerRequest: int32(c.Int64("max-stops-per-request")), - LogLevel: logLevel, + PublicHTTPAddr: c.String("public-http-addr"), + PublicGrpcAddr: c.String("public-grpc-addr"), + AdminHTTPAddr: c.String("admin-http-addr"), + AdminGrpcAddr: c.String("admin-grpc-addr"), + PostgresConnStr: c.String("postgres-connection-string"), + MaxConnections: int32(c.Int64("max-connections")), + EnableScheduler: c.Bool("enable-scheduler"), + EnablePublicMetrics: c.Bool("enable-public-metrics"), + ReadOnly: c.Bool("read-only"), + EnablePprof: c.Bool("enable-pprof"), + MaxStopsPerRequest: int32(c.Int64("max-stops-per-request")), + MaxVehiclesPerRequest: int32(c.Int64("max-vehicles-per-request")), + LogLevel: logLevel, } ctx, cancel := context.WithCancel(c.Context) ch := make(chan os.Signal, 1)